I have a database table with two field of type varbinary(max), which i use to store files.
However, I am unable to upload the files as expected. I've been stumped for this problem for a long time and I'm not sure what I can do to resolve it. There is an error message:
An exception of type 'System.Data.SqlClient.SqlException' occurred in
System.Data.dll but was not handled in user code
Additional information: Incorrect syntax near the keyword 'title'.
Its a must for me to implement 3-tier architecture in ASP.NET.
Data Access Layer
public class Submission {
private string _title;
private byte[] _slides, _codes;
//Connection string
private string _connStr = Properties.Settings.Default.DBConnStr;
public Submission(string title, byte[] slides, byte[] codes) {
_title = title;
_slides = slides;
_codes = codes;
}
//UPLOAD files
public int SubmissionInsert()
{
string queryStr = "INSERT INTO Submission(title,slides,codes)" +
"VALUES('" +
_title + "', '" +
_slides + "', '" +
_codes + "')";
SqlConnection con = new SqlConnection(_connStr);
SqlCommand cmd = new SqlCommand(queryStr, con);
con.Open();
int nofRow = 0;
nofRow = cmd.ExecuteNonQuery();
con.Close();
return nofRow;
}
}
Business Logic Layer
public class SubmissionBLL
{
public string submissionUpload(string title, byte[] slides, byte[] codes)
{
string returnValue = "";
if (title.Length == 0)
returnValue+= "Title cannot be empty";
if (slides == null)
returnValue += "Slides cannot be empty";
if (codes == null)
returnValue += "Codes cannot be empty";
//if there are no errors
if (returnValue.Length == 0)
{
Submission sub = new Submission(title,slides,codes);
int nofRows = 0;
nofRows = sub.SubmissionInsert();
if (nofRows > 0)
returnValue = "Submission is successful!";
else
returnValue = "Submission failure. Please try again.";
}
return returnValue;
}
Presentation Layer - Code-behind
protected void btn_submit_Click(object sender, EventArgs e)
{
string input = "";
byte[] slideArr = null, codeArr= null;
string strTestFilePath, strTestFileName, strContentType;
Int32 intFileSize, intFileLength;
Stream strmStream;
if (f_codes.HasFile)
{
strTestFilePath = f_codes.PostedFile.FileName;
strTestFileName = Path.GetFileName(strTestFilePath);
intFileSize = f_codes.PostedFile.ContentLength;
strContentType = f_codes.PostedFile.ContentType;
//Convert the source codes file to byte stream to save to database
strmStream = f_codes.PostedFile.InputStream;
intFileLength = (Int32)strmStream.Length;
codeArr = new byte[intFileLength + 1];
strmStream.Read(codeArr, 0, intFileLength);
strmStream.Close();
}
if (f_slide.HasFile)
{
strTestFilePath = f_slide.PostedFile.FileName;
strTestFileName = Path.GetFileName(strTestFilePath);
intFileSize = f_slide.PostedFile.ContentLength;
strContentType = f_slide.PostedFile.ContentType;
strmStream = f_slide.PostedFile.InputStream;
intFileLength = (Int32)strmStream.Length;
slideArr = new byte[intFileLength + 1];
strmStream.Read(slideArr, 0, intFileLength);
strmStream.Close();
}
//Pass to BLL
input = sub.submissionUpload(tb_title.Text,slideArr,codeArr);
//Display error messages
lbl_message.Text = input;
}
I tried to debug with IntelliTrace and it shows a message
ADO.NET:Execute NonQuery "INSERT INTO Submission(title,slides,codes)VALUES( 'My Water Saving Project', 'System.Byte[]','System.Byte[]')"
Am I doing this correctly? I tried to run and the exception error is still
present.
string queryStr = "INSERT INTO Submission(title,slides,codes)" + "VALUES('"+
_title + "', '" +
"0x" + BitConverter.ToString(_slides).Replace("-", "")+ "', '" +
"0x" + BitConverter.ToString(_codes).Replace("-", "") + "')";
"0x" + BitConverter.ToString(_slides).Replace("-", "")+ "', '" +
You should not convert byte to string. Instead, you want to use the parametrized query (to avoid sql injection) and insert those byte arrays straight to database.
public int SubmissionInsert(string title, byte[] slides, byte[] codes)
{
int nofRow;
string query = "INSERT INTO Submission ( title, slides, codes )" +
"VALUES ( #Title, #Slides, #Codes );";
using (var con = new SqlConnection(_connStr))
{
con.Open();
using (var cmd = new SqlCommand(query, con))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#Title", title);
cmd.Parameters.AddWithValue("#Slides", slides);
cmd.Parameters.AddWithValue("#Codes", codes);
nofRow = cmd.ExecuteNonQuery();
}
}
return nofRow;
}
Your issue is with the type conversion. If you are inserting the value as a string (and you are by using those single quotes), you need to insert the HEX values, and prefix it with 0x.
This should help you out:
"0x" + BitConverter.ToString(byteArray).Replace("-", "")
I also got the same error when I am uploading doc USING ADO.NET and Storedproc.
I am using stored proc to upload word file to the table's column type varbinary(max).
There are so many examples with insert query to insert document but my scenario was stored proc. I spent lot of time in figuring out the solution.
Stored Proc:`Alter PROC [dbo].[usp_GMS_SaveEngagementDocument](
#pDocumentID INT=0,
#pEngagementID INT,
#pDocumentName NVARCHAR(100),
#pContentType NVARCHAR(100),
#pDocumentType NVARCHAR(100),
#pDocumentContent VARBINARY(max)=null,
#pUserID INT)
AS
BEGIN
--INSERT
END`
SOLUTION:
param = new SqlParameter();
param.ParameterName = "#pDocumentContent";
param.Direction = ParameterDirection.Input;
param.Value = document.DocumentContent;
param.DbType = DbType.Binary;
param.SqlDbType = SqlDbType.Binary;
paramList.Add(param);
Setting SQLDBType as Binary and DbType as Binary solved my problem In calling stored proc.
END
Related
Following is the code to upload file in party_images table.
protected void upload_Click(object sender, EventArgs e)
{
try
{
using (OracleConnection connection = new OracleConnection(conString))
{
connection.Open();
string filename = Path.GetFileName(FileUpload1.FileName);
string[] tokenize = filename.Split('.');
FileUpload1.SaveAs(Server.MapPath("~/files/") + descBox.Text + "." + tokenize[1]);
string sourceLoc = Server.MapPath("~/files/" + descBox.Text + "." + tokenize[1]);
FileStream fs = new FileStream(sourceLoc, FileMode.Open, FileAccess.Read);
byte[] ImageData = new byte[fs.Length];
fs.Read(ImageData, 0, System.Convert.ToInt32(fs.Length));
fs.Close();
String block = " BEGIN " +
" INSERT INTO party_images(party_id, sr_no, descr, party_image) VALUES ('"+Session["userId"]+"',"+srNo.Text+",'"+descBox.Text+"."+tokenize[1]+"', :1); " +
" END; ";
OracleCommand cmd = new OracleCommand();
cmd.CommandText = block;
cmd.Connection = connection;
cmd.CommandType = CommandType.Text;
OracleParameter param = cmd.Parameters.Add("blobtodb", OracleDbType.LongRaw);
param.Direction = ParameterDirection.Input;
param.Value = ImageData;
cmd.ExecuteNonQuery();
descBox.Text = "";
srNo.Text = "";
}
}
catch (Exception ex) {
ClientScript.RegisterStartupScript(this.GetType(), "unSuccessMessage", "window.onload = function(){ alert('"+ex.Message+"')};", true);
}
finally
{
populateGrid(loadFromDb());
}
}
table description is,
PARTY_ID is VARCHAR2(10)
SR_NO is NUMBER
DESCR is VARCHAR2(50)
PARTY_IMAGE is LONG RAW()
This function is uploading all the files i.e., images,.docx,.pdf,.sql but when I upload any .docx containing screen shots or pictures then the upper error appears.
I have tried the following links,
ORA-01460: unimplemented or unreasonable conversion requested
The requested format conversion is not supported.
ORA-01460: unimplemented or unreasonable conversion requested
But I haven't got any solution. How can I upload any type of file without having this error?
Why are you using LONG RAW to store binary objects? That's a datatype which has been deprecated for over twenty years.
If you define PARTY_IMAGE as a BLOB (or maybe BFILE) you will find it a lot easier to work with. Find out more.
I created Sql Update procedure using c# dynamic object ( here it is 'string,string' dictionary - 'sql_fields_name,value_to_insert' ) which works well.
public static string sp_UpdateDB(int ID, dynamic a, string procName, string connString)// update using stored procedures
{
string resp=string.Empty;
string conn_string = ConfigurationManager.AppSettings.Get(connString);
using (System.Data.SqlClient.SqlConnection conn = new SqlConnection(conn_string))
{
try
{
conn.Open();
SqlCommand cmd = new SqlCommand(procName, conn);
cmd.CommandType = CommandType.StoredProcedure;
// set id of updated record
cmd.Parameters.Add(new SqlParameter("#ID", SqlDbType.Int));
cmd.Parameters["#ID"].Value = ID;
// set all fields and values
var attribList = a.Keys;
foreach (var entry in attribList)
{
cmd.Parameters.Add(new SqlParameter("#" + entry, SqlDbType.NVarChar, -1));
cmd.Parameters["#" + entry].Value = (a[entry] == "") ? (object)System.DBNull.Value : a[entry];
}
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
resp += ex.Message;
}
}
return resp;
}
and Sql server procedure
ALTER PROCEDURE [dbo].[UpdateDB]
-- Add the parameters for the stored procedure here
#ID int = null
,#JSON_Content nvarchar(max)= NULL
,#number nvarchar(max)= NULL
,#email nvarchar(max)= NULL
,#first_name nvarchar(max)= NULL
,#JSON_changes nvarchar(max)= NULL
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
UPDATE [Intranet].[dbo].[Applications]
SET
[JSON_Content] = ISNULL(#JSON_Content ,[JSON_Content])
,[staff_number] = ISNULL(#staff_number ,[staff_number])
,[staff_email] = ISNULL(#staff_email ,[staff_email])
,[first_name] = ISNULL(#first_name ,[first_name])
,[JSON_changes] = ISNULL(#JSON_changes ,[JSON_changes])
WHERE
[ID]=#ID
END
Now, I would like to make the same with insert into and I am stuck. Can someone turn me to the right direction? I have got only c# version, I can't make it as a sql stored procedure.
Present code:
public static string insertDB(dynamic a, out int id, string tableName, string connString)
{
string resp = "";
string strSQL = "";
id = 0;
try
{
var attribList = a.Keys;
string updateFields = "";
string updateValues = "";
foreach (var entry in attribList)
{
if (updateFields != "")
updateFields += ",";
if (updateValues != "")
updateValues += ",";
updateFields += "[" + entry + "]";
updateValues += "'" + a[entry] + "'";
}
string conn_string = ConfigurationManager.AppSettings.Get(connString);
SqlConnection conn = new SqlConnection(conn_string);
conn.Open();
strSQL = "insert into " + tableName + " ( " + updateFields + " ) VALUES ( " + updateValues + " )";
SqlCommand pushCommand = new SqlCommand(strSQL, conn);
pushCommand.ExecuteNonQuery();
pushCommand.CommandText = "Select ##Identity"; // get the just created record's ID
id = System.Convert.ToInt32(pushCommand.ExecuteScalar());
conn.Close();
}
catch (Exception ex) { resp += ex.ToString()+" id:"+id.ToString() + " " + strSQL; }
return resp;
}
My code is producing an Incorrect syntax near '(' exception. I have tried two different ways but they both produce the same exception. I am trying to update a record in the database.
Here is my code and the line that produces the exception is the Execute non query line. The updater.Fill(dtable) which is commented out also produces the same exception.
protected void btnSave_Click(object sender, EventArgs e)
{
int found = 0; // No match found so far
// Get the current selected Manufacturer
string currentManufacturer = grdManufact.SelectedRow.Cells[1].Text;
string currentIsModerated = grdManufact.SelectedRow.Cells[3].Text;
// Connect to the database
string strConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString2"].ToString();
SqlConnection conn = new SqlConnection(strConnectionString);
conn.Open();
// Try to find if new record would be a duplicate of an existing database record
if (txtManufactureName.Text != currentManufacturer)
{
string findrecord = "SELECT * From VehicleManufacturer WHERE ManufacturerName = '" + txtManufactureName.Text + "'";
SqlDataAdapter adpt = new SqlDataAdapter(findrecord, conn);
DataTable dt = new DataTable();
found = adpt.Fill(dt);
}
if (found == 0) // New record is not a duplicate you can proceed with record update
{
String query;
if (checkBoxModerated.Checked)
{
query = "UPDATE VehicleManufacturer (ManufacturerName, ManufacturerDescription, Ismoderated) Values ('" + txtManufactureName.Text + "','" + txtDescription.Text + "','true') WHERE ManufacturerName = " + currentManufacturer + ";";
}
else
{
query = "UPDATE VehicleManufacturer (ManufacturerName, ManufacturerDescription, Ismoderated) Values ('" + txtManufactureName.Text + "','" + txtDescription.Text + "','false') WHERE ManufacturerName = " + currentManufacturer + ";";
}
using (SqlCommand command = new SqlCommand(query, conn))
{
command.ExecuteNonQuery();
}
//using (SqlDataAdapter updater = new SqlDataAdapter(command))
// {
// DataTable dtable = new DataTable();
// updater.Fill(dtable);
// }
txtMessage.Text = "Manufacturer record changed Successfully";
txtManufactureName.Text = "";
txtDescription.Text = "";
checkBoxModerated.Checked = false;
}
else
{ // Record is a duplicate of existing database records. Give error message.
txtMessage.Text = "Sorry, that manufacturer name already exists.";
}
}
You are using the incorrect syntax for UPDATE statements.
Instead of
UPDATE Table (Fields) VALUES (Values) WHERE ...
It should be
UPDATE Table SET Field1=Value1, Field2=Value2 WHERE ...
Additionally, you have a SQL injection vulnerability (although this is not the reason for your exception).
Do not use string concatenation for SQL queries with user input. Use prepared statements instead.
Try this approach , it's safer also:
var isModerated = checkBoxModerated.Checked ; //true or false
//var isModerated = (checkBoxModerated.Checked)? 'true' : 'false' ;
command.Text = "UPDATE VehicleManufacturer
SET ManufacturerName = #manufacturerName,
ManufacturerDescription = #manufacturerDescription,
IsModerated = #isModerated
WHERE ManufacturerName = #manufacturer_name";
command.Parameters.AddWithValue("#manufacturerName", txtManufactureName.Text);
command.Parameters.AddWithValue("#manufacturerDescription", txtDescription.Text);
command.Parameters.AddWithValue("#isModerated", isModerated);
command.Parameters.AddWithValue("#manufacturer_name", txtManufactureName.Text);
command.ExecuteNonQuery();
i have a zip file stored in a table by a third party application which i have no control over. I do however have access to the MySQL DB.
What i want to do is do a SELECT statement to retrieve a blob field and copy this record into another table. But on the other side, i do see the blob field on the far side but it is not a zip file, its a text file that says System.Byte[] and thats it - anyone any ideas on what is causing this and how to fix it?
heres what i have below - again any help greatly appreciated :)
OdbcCommand broadcastSelect = new OdbcCommand("select * from exchange where status='1' and type='UPDATE'", cloud);
OdbcDataReader DbReader = Select.ExecuteReader();
int fCount = DbReader.FieldCount;
String type = "";
String filename = "";
byte[] data = null;
int status = 0;
while (DbReader.Read())
{
if (DbReader.IsDBNull(0))
{
type = "BLANK";
}
else
{
type = (string)DbReader[0];
}
if (DbReader.IsDBNull(1))
{
filename = "BLANK";
}
else
{
filename = (string)DbReader[1];
}
if (DbReader.IsDBNull(2))
{
data = new byte[1];
}
else
{
data = (byte[])DbReader[2];
}
if (DbReader.IsDBNull(3))
{
status = 0;
}
else
{
status = (int)DbReader[3];
}
OdbcCommand Copy = new OdbcCommand("INSERT INTO exchange(type,filename,data,status) VALUES('" + type + "','" + filename + "','"
+ data + "','" + status + "')", local);
Copy.ExecuteNonQuery();
}
use sql parameter for inserting the binary data.
OdbcParameter param = new OdbcParameter("#file", SqlDbType.Binary);
---Updated
I hope below given code will be helpful to you.
OdbcCommand broadcastSelect = new OdbcCommand("select * from exchange where status='1' and type='UPDATE'", cloud);
OdbcDataReader DbReader = Select.ExecuteReader();
int fCount = DbReader.FieldCount;
String type = "";
String filename = "";
byte[] data = null;
int status = 0;
OdbcParameter param = null;
while (DbReader.Read())
{
if (DbReader.IsDBNull(0))
{
type = "BLANK";
}
else
{
type = (string)DbReader[0];
}
if (DbReader.IsDBNull(1))
{
filename = "BLANK";
}
else
{
filename = (string)DbReader[1];
}
if (DbReader.IsDBNull(2))
{
param = new OdbcParameter("#file", SqlDbType.Binary);
param.DbType = DbType.Binary;
param.Value = new byte[1];
command.Parameters.Add(param);
}
else
{
param = new OdbcParameter("#file", SqlDbType.Binary);
param.DbType = DbType.Binary;
param.Value = (byte[])dbReader[2];
param.Size = ((byte[])dbReader[2]).Length;
command.Parameters.Add(param);
}
if (DbReader.IsDBNull(3))
{
status = 0;
}
else
{
status = (int)DbReader[3];
}
OdbcCommand Copy = new OdbcCommand("INSERT INTO exchange(type,filename,data,status) VALUES('" + type + "','" + filename + "',#file,'" + status + "')", local);
Copy.ExecuteNonQuery();
I am using the following code to insert StartDate(s) and EndDate(s) into my Iterations table. I am displaying the output in my textbox like this: dd/MM/yyyy, but am writing to my db as MM/dd/yyyy, because of the datetime data type - hence I'm using:
System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("en-GB");
sc.Add(proj_id + "," + Convert.ToDateTime(box1.Text, ci) + "," + Convert.ToDateTime(box2.Text, ci));
I'm pretty sure this code worked just fine on localhost, but when I uploaded it to a server, I am getting the error: Insert error: the conversion of a varchar datatype to a datetime data type resulted in an out-of-range value. Please help! thanks!
Here's the full code:
private void InsertRecords(StringCollection sc)
{
SqlConnection conn = new SqlConnection(GetConnectionString());
StringBuilder sb = new StringBuilder(string.Empty);
string[] splitItems = null;
foreach (string item in sc)
{
const string sqlStatement = "INSERT INTO Iterations (ProjectID, StartDate, EndDate) VALUES";
if (item.Contains(","))
{
splitItems = item.Split(",".ToCharArray());
sb.AppendFormat("{0}('{1}','{2}','{3}'); ", sqlStatement, splitItems[0], splitItems[1], splitItems[2]);
}
}
string sql = "INSERT INTO ProjectIterationMember (ProjectIterationID, MemberID) SELECT ProjectIterationID AS pro_it_id, #member_id FROM Iterations WHERE ProjectID = '" + proj_id + "'";
try
{
conn.Open();
SqlCommand cmd = new SqlCommand(sb.ToString(), conn);
SqlCommand cmd2 = new SqlCommand(sql, conn);
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
SqlParameter memberParameter = new SqlParameter("#member_id", SqlDbType.Int);
cmd2.Parameters.Add(memberParameter);
cmd2.CommandType = CommandType.Text;
cmd2.Prepare();
memberParameter.Value = project_manager.SelectedValue;
cmd2.ExecuteNonQuery();
for (int i = 0; i < project_members.Items.Count; ++i)
{
if (project_members.Items[i].Selected)
{
memberParameter.Value = project_members.Items[i].Value;
cmd2.ExecuteNonQuery();
}
}
//Display a popup which indicates that the record was successfully inserted
Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "Script", "alert('New iterations were successfully added!');", true);
}
catch (System.Data.SqlClient.SqlException ex)
{
string msg = "Insert Error:";
msg += ex.Message;
throw new Exception(msg);
}
finally
{
conn.Close();
}
}
protected void btnSaveIterations_Click(object sender, EventArgs e)
{
int rowIndex = 0;
StringCollection sc = new StringCollection();
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
//extract the TextBox values
TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[1].FindControl("start_iteration");
TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[2].FindControl("end_iteration");
System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("en-GB");
//get the values from the TextBoxes
//then add it to the collections with a comma "," as the delimited values
sc.Add(proj_id + "," + Convert.ToDateTime(box1.Text, ci) + "," + Convert.ToDateTime(box2.Text, ci));
rowIndex++;
}
//Call the method for executing inserts
InsertRecords(sc);
Response.Redirect(Request.Url.ToString());
//r.Close();
//conn.Close();
}
}
}
First of all: concatenating together your INSERT statement is really really bad practice and opens the door to SQL Injection. Don't do it - use parametrized queries instead!
const string sqlStatement =
"INSERT INTO Iterations (ProjectID, StartDate, EndDate) " +
"VALUES(#ProjectID, #StartDate, #EndDate)";
and here:
string sql =
"INSERT INTO ProjectIterationMember (ProjectIterationID, MemberID) " +
"SELECT ProjectIterationID AS pro_it_id, #member_id " +
"FROM Iterations WHERE ProjectID = #ProjectID";
You will need to setup parameters for your SqlCommand and pass in the values before executing the query.
SqlCommand _cmd = new SqlCommand(sqlStatement, _connection);
_cmd.Parameters.Add("#ProjectID", SqlDbType.Int);
_cmd.Parameters["#ProjectID"].Value = 42;
_cmd.Parameters.Add("#StartDate", SqlDbType.DateTime);
_cmd.Parameters["#StartDate"].Value = Convert.ToDateTime(your textbox string);
_cmd.Parameters.Add("#EndDate", SqlDbType.DateTime);
_cmd.Parameters["#EndDate"].Value = Convert.ToDateTime(your textbox string);
Second: SQL Server has a range from 1/1/1753 to the end of the year 9999 - if any of your strings represent a date before 1753, you're getting this problem. Validate your inputs! When you use parametrized queries, you can do this at the point where you're setting the values of the SqlCommand.Parameters - anything outside the range that SQL Server supports (e.g. dates like "1/1/0001" and so forth) must be "sanitized" before being passed into SQL Server.