I have an ASP.Net form, where it grabs a value from a textbox:
<asp:TextBox ID="txtID" runat="server" maxlength=9></asp:TextBox>
The ID HAS to be 9 numbers.
After it grabs it, I want to insert it into a database (SQL Server 2005), so I build a parameterized string,
'The Query
cmd.CommandText = "insert into table (aid) values ('#aid')"
cmd.Connection = conn
'Grab the value
cmd.Parameters.add("#aid", SqlDBType.Int).value = txtID.text
'Execute!
cmd.Connection.Open()
cmd.ExecuteNonQuery
However, it doesn't let me. It keeps giving the following error message:
Conversion failed when converting the varchar value '#aid' to data type int.
So I've tried a variety of things:
cmd.Parameters.add("#aid", SqlDBType.Int).value = 999999999
cmd.Parameters.add("#aid", SqlDBType.Int).value = Convert.ToInt16(txtID.text)
cmd.Parameters.add("#aid", SqlDBType.Int).value = Convert.ToInt32(txtID.text)
cmd.Parameters.add("#aid", SqlDBType.Int).value = Convert.ToInt64(txtID.text)
Nothing works. Inside the database, the type is "int".
Any ideas?
Remove the quotes around #aid in your query, so that it looks like so:
cmd.CommandText = "insert into table (aid) values (#aid)"
Otherwise, you're sending the code mixed messages. Parameters are never enclosed in quotes. They are string literals if they're enclosed in quotes. Additionally, in pure SQL, numbers are not enclosed in quotes, but text values (varchar and the like) are. So, remove the quotes, and the parameter should have no issues being created.
Parameters aren't inserted straight into SQL wholesale. They're plopped in after SQL Server has parsed the query. Therefore, parameters should just be on their own, as they're taken as string literals if they aren't. The parameterization will take care to convert the parameter to the right data type for you. See this post for more on how parameters work behind the scenes.
Your sql query is the problem.
You are trying to do
INSERT INTO TABLE(aid) VALUES('123456789')
You need to drop the quotes and do
INSERT INTO TABLE(aid) VALUES(123456789)
Related
I'm currently using the following VB code to make a query against an Access Database, I would like to know is it possible to obtain what the SELECT statement that is being run and send that output to the console.
Dim QuestionConnectionQuery = New OleDb.OleDbCommand("SELECT Questions.QuestionID FROM Questions WHERE Questions.QuestionDifficulty=[X] AND ( Questions.LastDateRevealed Is Null OR Questions.LastDateRevealed < DateAdd('d',-2,Date() ) AND Questions.LastUsedKey NOT LIKE ""[Y]"" );", QuestionConnection)
QuestionConnectionQuery.Parameters.AddWithValue("X", questionDifficulty.ToString)
QuestionConnectionQuery.Parameters.AddWithValue("Y", strDatabaseKey)
Right now when I try to use: Console.WriteLine("Query: " & QuestionConnectionQuery.ToString)
I only get this:
Loop Question #1
Query: System.Data.OleDb.OleDbCommand
The short version comes down to this:
QuestionConnectionQuery.ToString
The QuestionConnectionQuery object is much more than just the text of your command. It's also the parameters, execution type, a timeout, and a number of other things. If you want the command text, ask for it:
QuestionConnectionQuery.CommandText
But that's only the first issue here.
Right now, your parameters are not defined correctly, so this query will never succeed. OleDb uses ? as the parameter placeholder. Then the order in which you add the parameters to the collection has to match the order in which the placeholder shows in the query. The code in your question just has X and Y directly for parameter placeholders. You want to do this:
Dim QuestionConnectionQuery AS New OleDb.OleDbCommand("SELECT Questions.QuestionID FROM Questions WHERE Questions.QuestionDifficulty= ? AND ( Questions.LastDateRevealed Is Null OR Questions.LastDateRevealed < DateAdd('d',-2, Date() ) AND Questions.LastUsedKey NOT LIKE ? );", QuestionConnection)
QuestionConnectionQuery.Parameters.Add("?", OleDbType.Integer).Value = questionDifficulty
QuestionConnectionQuery.Parameters.Add("?", OleDbType.VarChar, 20).Value = strDatabaseKey
I had to guess at the type and lengths of your parameters. Adjust that to match the actual types and lengths of the columns in your database.
Once you have made these fixes, this next thing to understand is that the completed query never exists. The whole point of parameterized queries is parameter data is never substituted directly into the sql command text, not even by the database engine. This keeps user data separated from the command and prevents any possibility of sql injection attacks.
While I'm here, you may also want to examine the WHERE conditions in your query. The WHERE clause currently looks like this:
WHERE A AND ( B OR C AND D )
Whenever you see an AND next to an OR like that, within the same parenthetical section, I have to stop and ask if that's what is really intended, or whether you should instead close the parentheses before the final AND condition:
WHERE A AND (B OR C) AND D
This will fetch the command text and swap in the parameter values. It isnt necessarily valid SQL, the NET Provider objects haven't escaped things yet, but you can see what the values are and what the order is for debugging:
Function GetFullCommandSQL(cmd As Data.Common.DbCommand) As String
Dim sql = cmd.CommandText
For Each p As Data.Common.DbParameter In cmd.Parameters
If sql.Contains(p.ParameterName) AndAlso p.Value IsNot Nothing Then
If p.Value.GetType Is GetType(String) Then
sql = sql.Replace(p.ParameterName,
String.Format("'{0}'", p.Value.ToString))
Else
sql = sql.Replace(p.ParameterName, p.Value.ToString)
End If
End If
Next
Return sql
End Function
Given the following SQL:
Dim sql = "INSERT INTO Demo (`Name`, StartDate, HP, Active) VALUES (#name, #start, #hp, #act)"
After parameters are supplied, you can get back this:
INSERT INTO Demo (`Name`, StartDate, HP, Active) VALUES ('johnny', 2/11/2010 12:00:00 AM, 6, True)
It would need to be modified to work with OleDB '?' type parameter placeholders. But it will work if the DbCommand object was created by an OleDBCOmmandBuilder, since it uses "#pN" internally.
To get or set the text of the command that will be run, use the CommandText property.
To print the results, you need to actually execute the query. Call its ExecuteReader method to get an OleDbDataReader. You can use that to iterate over the rows.
Dim reader = QuestionConnectionQuery.ExecuteReader()
While reader.Read
Console.WriteLine(reader.GetValue(0))
End While
reader.Close()
If you know the data type of the column(s) ahead of time, you can use the type-specific methods like GetInt32. If you have multiple columns, change the 0 in this example to the zero-based index of the column you want.
I need to update some code and as part of this I need to insert a row into a table and obtain the id (primary key) of the row just entered.
Have researched this and I believe I should be using RETURNING INTO and Oracle Parameters. I have used parameters in the past successfully to Insert values.
I have an INSERT statement that runs perfectly from VB.NET, but as soon as I add the text "" RETURNING id INTO :myId" I get ORA-00933 Command Not Properly Ended.
Here is a version of the code.
sql = "INSERT ... RETURNING id INTO :myId"
Connect()
Dim intRecsAffected As Integer = 0
Dim comm As OracleCommand = New OracleCommand(sql, _conn)
Dim param As OracleParameter
param = New OracleParameter()
param.ParameterName = ":myId"
param.OracleDbType = OracleDbType.Int32
param.Direction = ParameterDirection.Output ' Tried ReturnValue
comm.Parameters.Add(param)
intRecsAffected = comm.ExecuteNonQuery()
id = comm.Parameters(":myId").Value
Disconnect()
Any ideas?
I believe that your syntax is incorrect:
sql = "INSERT ... RETURNING id INTO myId"
Example below:
https://oracle-base.com/articles/misc/dml-returning-into-clause
Actually, realised what was going on. I cut my full SQL as it's quite long and there's some sensitive stuff in there.
The INSERT was using a SELECT rather than VALUES to get the values for the fields. That won't work - I am guessing because an INSERT with SELECT can add multiple rows even though in this case it won't.
Have re-written the SQL to use VALUES and the VB.Net code works fine.
Thanks to all who replied.
I am trying to pass my query string into database using VB.NET, but I am seeing a syntax error. I don't know where it is, please help me!
Me.str = String.Concat(New String()
{"Insert into Sales values('",
Me.txtVoucherNo.Text, "','", dtpDate.Value, "','",
dtpMonth.Value, "','", POSPage.txtPatientNo.Text, "','",
POSPage.txtPatientName.Text, "','",
POSPage.txtAddress.Text, ",'--',", POSPage.txtsubtotal.Text, "','",
POSPage.txtTax.Text, ",'--',", POSPage.txtdiscount.Text, "','",
POSPage.txtGrandTotal.Text, "')"})
Nooooooooooooo!
String edits like that leave you vulnerable to sql injection attacks. It's practically begging to get hacked.
You want something more like this:
Using cn As New SqlConnection(" connection string here "), _
cmd As New SqlCommand(
"Insert into Sales VALUES ( #VoucherNo, #Date, #Month, #PatientNo, #PatientName, #Address, '--', #SubTotal, #Tax, '--', #Discount, #GrandTotal )"
, cn )
'change this to use the actual column types and lengths in your database
cmd.Parameters.Add("#VoucherNo", SqlDbType.NVarChar, 10).Value = Me.txtVoucherNo.Text
cmd.Parameters.Add("#Date", SqlDbType.DateTime).Value = dtpDate.Value
cmd.Parameters.Add("#Month", SqlDbType.DateTime).Value = dtpMonth.Value
cmd.Parameters.Add("#PatientNo", SqlDbType.NVarChar, 10).Value = POSPage.txtPatientNo.Text
cmd.Parameters.Add("#PatientName", SqlDbType.NVarChar, 50).Value = POSPage.txtPatientName.Text
cmd.Parameters.Add("#Address", SqlDbType.NVarChar, 250).Value = POSPage.txtAddress.Text
cmd.Parameters.Add("#SubTotal", SqlDbType.Decimal).Value = Convert.ToDecimal(POSPage.txtsubtotal.Text)
cmd.Parameters.Add("#Tax", SqlDbType.Decimal).Value = Convert.ToDecimal(POSPage.txtTax.Text)
cmd.Parameters.Add("#Discount", SqlDbType.Decimal).Value = Convert.ToDecimal(POSPage.txtdiscount.Text)
cmd.Parameters.Add("#GrandTotal", SqlDbType.Decimal).Value = Convert.ToDecimal(POSPage.txtGrandTotal.Text)
cn.Open()
cmd.ExecuteNonQuery()
End Using
Note that, with this code, the SQL string itself is constant. Instead of a string field in your class (Me.Str), you need the full SqlCommand object, so that you can hold both the sql statement and the parameter data.
If you still have trouble with this, try including the names of the columns before the VALUES() clause.
That out of the way, original syntax error was because of this sequence in your string array:
"','", POSPage.txtAddress.Text, ",'--',"
Note that this would open a quoted field in your query, but not close it until after the comma. What comes next is a comment marker in Sql Server. In short, if you actually enter the name of the field as the address, you'd get this:
'POSPage.txtAddress.Text,'--
Everything after the two hyphens would be commented out, including the closing parentheses for your VALUES clause, meaning the query is not valid SQL syntax... assuming someone hasn't already used sql injection on another field to include put whatever sql statement they want as part of the query.
I won't tell you how to just fix that error, because it should be obvious now, and well... there's that pesky injection problem again. I will say that you made the same mistake with the other ",'--'," string later in the query.
In my current vb.net (visual studio 2010) project I am dealing with SQL Server CE data base.
For storing mobile numbers, I am using nvarchar data type for Mobile_no field.
while testing i have entered 1234567890 in field Mobile_no successfully..
But at the time of retrieval i am getting this error :
Expression evaluation caused an overflow. [Name of function (if known)=]
So what should i do to store mobile numbers in sql ce data base ?
EDIT :
Code for Insert :
Dim SQLquery As String
Dim enumber As String
enumber = 1234567890
insqertSql = "INSERT INTO tbl_cust(c_id,Mobile_no) VALUES(#CId, #Phno)"
Dim cmd As New SqlCeCommand(insqertSql, con)
cmd.Parameters.Add("#CId", c_id)
cmd.Parameters.Add("#Phno", enumber)
cmd.ExecuteNonQuery()
Query for retrieval :
SQLquery = "SELECT * FROM tbl_cust WHERE ePhone =" & txt_number.text
The problem is in the string concatenation in the retrieve query.
SQLquery = "SELECT * FROM tbl_cust WHERE ePhone =" & txt_number.text
Here, you miss the single quotes that should enclose a string value when used as a WHERE condition.
However, in your INSERT query you use a parameterized approach, why you don't use the same approach for the select?
SQLquery = "SELECT * FROM tbl_cust WHERE ePhone = #number"
Dim cmd As New SqlCeCommand(SQLquery, con)
cmd.Parameters.Add("#number", txt_Number.Text)
SqlCeDataReader reader = cmd.ExecuteReader()
........
If you use a parameterized query, the proper handling of string quotes, decimal numbers and date formatting is passed to the underlying framework code that knows better than you and me how to pass these values to the database engine. Also, the parameterized query remove any possibilities of Sql Injection.
While using sql 2005, it appears I am unable to insert more than 8000 characters in a nvarchar(max) field.
This is really puzzling. I have tried insert, update and update .write with no luck. I can't insert it completely in the console and in .net the error I consistently get is
The data types text and varchar are incompatible in the add operator.
The insert statement is
insert into tablename (columnname) values (' long text');
Update:
update tablename set columnname='long text'
Everything is always truncated at 8000 characters (the text is 11,000 characters). Running a few tests, I see that
select ##textsize
gives 2147483647
Any ideas what I might be doing wrong here?
Your code truncates the value somewhere. You did not include the entire code, so we cannot guess where it truncates. The usual place is parameter declarations. The correct code should be like this:
SqlCommand cmd = new SqlCommand(
#"insert into table (column) values (#param)", conn, trn);
cmd.Paramaters.Add("#param", SqlDbType.NVarChar, -1);
cmd.Parameters["#param"].Value = myLongVariable;
cmd.ExecuteNonQuery();
using (System.Data.SqlClient.SqlConnection con = new
SqlConnection("YourConnection string"))
{
con.Open();
using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand())
{
string expression = "long text.................................";
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Your Stored Procedure";
cmd.Parameters.Add("Your long text Parameter Name ",
SqlDbType.NVarChar).Value = expression;
cmd.Connection = con;
cmd.ExecuteNonQuery();
}
}
I've just had this issue and eventually tracked it down to the ADO constant I was using in the VBA code that calls the stored procedure. Originally I was adVarChar which gave me the "String data, right truncation" message, but when I swapped this out for adLongVarChar it now works fine
cmd.Paramaters.Add("#param", SqlDbType.NVarChar, -1).Value=parametervaluehere;
where -1 means max length for varchar/nvarchar datatype.