How to insert pdf file into sql-server - c#

I have an C# API which I use to read and insert pdf files into sql-server table.
On the front-end side I have an React-application which consumes the API to do CRUD operations.
The react part works perfectly, I can do all the operations and I have no error/warning there.
I have already inserted some PDF documents into my table with this query:
INSERT INTO [DEFLEGOPINION] (content,extension,title)
SELECT BulkColumn , '.pdf' , 'Title123'
FROM OPENROWSET(BULK N'C:\temp\test.pdf', SINGLE_BLOB) AS BulkColumn
SELECT CAST('string' as varbinary(max)) FOR XML PATH(''), BINARY BASE64
So when I try to open and read these documents which are inserted this way, I can easily do that without any problem.
On the other hand, when I insert new files from API, the insertion works correctly but when I try to open the file it says that it's in a bad/corrupted format...
Here's how am I trying to insert files from c# api:
connection.Open();
string[] newContent = content.Split(',');
//here I removed the 'data:application/pdf;base64' part since I read somewhere that this makes a problem and should be remove
string encodedStr = Convert.ToBase64String(Encoding.UTF8.GetBytes(content));
String sql = "INSERT INTO myTable(Id,Name,Content) values('" + Guid.NewGuid() + "', '"
+ name + "', CONVERT(varbinary(max), '" + newContent[1] + "', 0))";
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.ExecuteNonQuery();
return true;
}
//Note:Name and Content are string parameters
Since the react part work as it should reading other documents, I don't think I have an issue there.
What am I missing? Should I change something on the method I use on the c# side or should I implement the first method but with the use of a file path (which it will be dynamic and I cannot know the user's file path's)

Posting this here so it might help someone else in the future.
I just found out that it is a must to use parameters in order to insert a file into sql-server from c# api.
It goes like this:
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.Parameters.Add(new SqlParameter("#Ident", Guid.NewGuid()));
command.Parameters.Add(new SqlParameter("#Name", name));
command.Parameters.Add(new SqlParameter("#Content", file));
command.ExecuteNonQuery();
}

Related

how to create user define tables by ADO.net

A desktop-based software shall enable a user to create tables in a provided database as per requirement.
My problem is that ExecuteNonQuery treats only Data Manipulation Language.
What should i use for Data Definition Language, i.e to pass create command.
Thanks in advance :)
my code
3rd party edit
From the linked image
public void create(string name, int varchar_quantity, string rate)
{
con.Close();
string s = "Crate table anas('" + name + "' varchar ('"
+ varchar_quantity + "')" + rate + "' int);";
con.Open();
SqlCommand com = new SqlCommand(s, con);
com.ExecuteNonQuery();
}
You should be able to create tables with ExecuteNonQuery method.
From msdn documentation,
You can use the ExecuteNonQuery to perform catalog operations (for
example, querying the structure of a database or creating database
objects such as tables), or to change the data in a database without
using a DataSet by executing UPDATE, INSERT, or DELETE statements.
var conStr = "PUT YOUR CONNECTION STRING HERE";
using (var c = new SqlConnection(conStr))
{
c.Open();
var qry = "CREATE TABLE TEST(name varchar(30));";
using (var cmd = new SqlCommand(qry, c))
{
cmd.ExecuteNonQuery();
}
}

Vistadb Writing SQL For Image DataType

I have recently started a new job and they use Vistadb so I cannot change the software package before people suggest that. I have obtained out of the database a byte[] from a datatype of image that is used in there different systems so its data type cannot be changed from image to varbinary. I have made alterations to the byte[] and now need to put it back into the database in an new record however I cant seem to work out how the SQL Query should be for it so far I have.
zz is the byte[] the rest of it works fine just need a way to put that into my SQL Query
sql = "INSERT INTO TimeHistory(\"Data\",\"Name\",\"Units\",\"ParameterData\",\"StartTime\",\"EndTime\",\"StorageRate\",\"Measurement\") SELECT \'" +zz+ "\',\'" + Name + "\',\'" + Units + "\',\'" + ParameterData + "\',\'" + start + "\',\'" + end + "\',\'" + storage + "\'" + ",SELECT Max(ID)From Measurement;";
ExecuteScript(sql);
This is done with c#.net using WPF forms.
The key to doing what you want is to use parameters to pass data to your SQL operation, not to convert it to a string and embed it in the TSQL code. This is a best practice not just because it prevents needless type conversions (say from DateTime to string and string back to DateTime for storage) but also for security - it ensures the database engine only attempts to execute as code things you intended to be code, not data that happened to be escaped so it was evaluated as part of the string.
We have a good example of how to do this in our ADO.NET samples at:
Common Operations in ADO.NET
If you go down the page you'll see an example "Inserting Data Using a Parameterized Command" which will work with any type, like this:
using (VistaDBConnection connection = new VistaDBConnection())
{
connection.ConnectionString = #"Data Source=C:\mydatabase.vdb5";
connection.Open();
using (VistaDBCommand command = new VistaDBCommand())
{
int Age = 21;
command.Connection = connection;
command.CommandText = "INSERT INTO MyTable (MyColumn) VALUES (#age)";
command.Parameters.Add("#age", Age);
command.ExecuteNonQuery();
}
}

SqlFileStream - insert without producing a null file

I am using SqlFileStream to store files in a database, however I have a small issue when inserting new records that I can't seem to resolve! The problem lies with the fact that I need to create a temporary file when inserting a record to provide a file path to stream the actual filedata to. I was expecting the temporary file to be overwritten when the actual data is streamed to the file path but it actually adds another file - leaving the null file in the file system.
Here is the code (please ignore the query string format and the way I am inserting the parameters, I have been hacking away trying different things and have lost the will to code nicely ;) ):
using (TransactionScope transactionScope = new TransactionScope())
{
string InsertTSql = "Insert Into Documents(file_name, file_type, category, uploaded_by, file_data) values('" + request.fileInfo.fileName + "', '" + request.fileInfo.fileType + "', '" + request.fileInfo.category + "', '" + request.fileInfo.uploadedBy + "',Cast('' As varbinary(Max))); Select file_data.PathName() As Path From Documents Where document_id = ##Identity";
SqlConnection dbConnection = new SqlConnection(#"Data Source=SAM\SQLEXPRESS;Initial Catalog=PIRS;Integrated Security=True;MultipleActiveResultSets=True;Application Name=EntityFramework");//ConfigurationManager.ConnectionStrings["PIRSDBCon"].ToString()) )
var cmd = new SqlCommand(InsertTSql, dbConnection);
dbConnection.Open();
string filePath = (string)cmd.ExecuteScalar();
string GetTcTSql = "Select GET_FILESTREAM_TRANSACTION_CONTEXT() As TransactionContext";
cmd = new SqlCommand(GetTcTSql, dbConnection);
byte[] transactionContext =(byte[]) cmd.ExecuteScalar();
SqlFileStream sqlFileStream = new SqlFileStream(filePath, transactionContext, FileAccess.Write);
request.fileData.CopyTo(sqlFileStream);
sqlFileStream.Close();
transactionScope.Complete();
}
Please just let me know if I can add further information or more clarity regarding the issue.
The filestream system uses a garbage collector - every change always generates a new file, and then eventually the old file is deleted. But that doesn't happen instantly.
See e.g. How It Works: FileStream Garbage Collection or How It Works: File Stream the Before and After Image of a File for some discussion of the mechanics behind this.

Saving an image in an Informix database using C# code?

How do I save an image in an Informix database using C# code?
At the moment, I'm unable to save an image in an Informix database using C# code.
All the steps work, only when the query is about to get executed it throws error "E42000: (-201) A syntax error has occurred."
Below is the code.
mycon.Open();
int len = Upload.PostedFile.ContentLength;
byte[] pic = new byte[len];
HttpPostedFile img = Upload.PostedFile;
Response.Write("Size of file = " + pic);
img.InputStream.Read(pic, 0, len);
//Upload.PostedFile.InputStream.Read(pic,0,len);
string str = "insert into imageinfo (name,address,photo) values('" + txtname.Text + "','" + txtaddress.Text + "'," + pic + ")";//,photo,#photo
mycmd = new OleDbCommand(str, mycon);
//mycmd.Parameters.AddWithValue("#id", int.Parse(txtid.Text));
mycmd.Parameters.AddWithValue("#name", txtname.Text);
mycmd.Parameters.AddWithValue("#address", txtaddress.Text);
mycmd.Parameters.AddWithValue("#photo", pic);
mycmd.ExecuteNonQuery();
mycon.Close();
lblMessage.Text = "Image details inserted successfully";
Response.Redirect("~/RetriveImage.aspx");
mycon.Close();
It starts with your code being a copy/paste mess from at least 2 sources because it makes no sense.
Your insert has the values directly - and you can not put pic in like that, sorry - but you define parameters that are not used. 2 sources code.
Then the code was mindlessly copy/pasted. You define named paraameters, but OleDb does not support named parameters (http://social.msdn.microsoft.com/Forums/en-US/vsreportcontrols/thread/637db5d4-e205-489c-b127-7ca14abc48e3/) only parameter by position, which tells me you enver ever used parameters with Informix via OleDb and just copied/pasted the code together.
Remove the direct data in the INSERT statement, put in parameter markers.
Then use the parameters, as per the MS link I sent you (positional, marker is a ?).
Then it will work.
Occasionally it may require you to actually read the documentation instead of just stitching together code from different sources and asking for help.

Updating SQL column based on text file (foreach line in it)

What I have is an extremely large text file that needs to go into a specific column at a specific raw. The file is around 100k lines. So what I want to do is read the whole file, and for each line append into that specific SQL column the line. Here's what I have but i really need help on the SQL query
string[] primaryfix = File.ReadAllLines(dinfo+"\\"+filex);
string filename = filex.ToString();
string[] spltifilename = filename.Split('.');
foreach (string primary in primaryfix)
{
string sqltable = ("dbo.amu_Textloadingarea");
string sql = "update " + sqltable + " set [Text] = [Text] + '" + primary + "' where begbates = '" + spltifilename[0] + "'";
SqlConnection con = new SqlConnection("Data Source= Corvette ;Initial Catalog= GSK_Avandia_SSECASE;Integrated Security= SSPI");
con.Open();
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader reader = cmd.ExecuteReader();
con.Close();
}
everything is fine except for the string sql, it doesn't update the way I would like it to.
Any help is always appreciated.
Look likes you're trying to read from the database with that code inside the loop. SqlDataReader provides a way to read rows from the database, but not the other way around.
Replace
SqlDataReader reader = cmd.ExecuteReader();
with
cmd.ExecuteNonQuery();
The first thing I see is that you are not escaping the input from the text file; any SQL escape characters (like a single quote) will break that command. I'd recommend using parameters so you needn't worry about escapes at all.
Other than that, nothing pops to mind that would suggest why the command isn't working, but I do wonder if it might not cause fewer problems if it's such a large file to read it line-by-line rather than all at once.

Categories

Resources