How to pass the table name and the selected fields as parameters - c#

I get the following error :
ERROR:-201
MEssage: [Informix .NET provider][Informix]A syntax error has occurred.
when I try to execute this code :
string table_name = resultDt.Rows[0][1].ToString();
string pdf_column = resultDt.Rows[0][0].ToString();
st.Append(" SELECT ? FROM ?");
paramList.Clear();
paramList.Add("#tablename", table_name);
paramList.Add("#pdf_column", pdf_column);
resultDt =dalHelper.Return_DataTable(st.ToString(), CommandType.Text, paramList);
return resultDt;

You can't.
Use String.Replace instead.
st.Append(" SELECT #pdf_column FROM #tablename");
st.Replace("#tablename", table_name);
st.Replace("#pdf_column", pdf_column);
If table_name and pdf_column comes from user input in anyway you should use a QuoteName function (i.e. QuoteName(table_name)) to prevent sql injection. Don't know about Informix but here is one for SqlServer.

Related

Dapper reporting invalid syntax near parameter name when attempting to pass null in a DynamicParameter

I'm attempting to get all records from a table where a certain field is not a blank string or null. Due to the way I'm building the queries, ISNULL and COALESCE are not options here. Changing the schema of the database is not an option either.
This is the code I'm running to try to retrieve the records.
using System;
using System.Data.SqlClient;
using System.Linq;
using Dapper;
namespace DapperMCVE
{
internal class UserFinder
{
public static void Main(string[] args)
{
using (var connection = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;Integrated Security=True"))
{
connection.Execute(#"IF NOT EXISTS(SELECT * FROM sys.tables WHERE name = 'Users')
CREATE TABLE Users(NullableUserId varchar(50) NULL) ON [PRIMARY]");
connection.Execute(#"DELETE Users");
connection.Execute(#"INSERT INTO Users(NullableUserId)
VALUES(''), (NULL), ('SteveSmith#fake.com'), ('Morgan#totallyreal.org')");
var parameters = new DynamicParameters();
parameters.Add("UserIdNull", (string)null);
parameters.Add("UserIdBlank", "");
try
{
var users = connection.Query(#"SELECT *
FROM Users
WHERE NullableUserId IS NOT #UserIdNull
AND NullableUserId != #UserIdBlank", parameters);
Console.WriteLine(users.ToList());
}
catch (SqlException e)
{
Console.WriteLine(e);
}
Console.ReadKey();
}
}
}
}
The error thrown is System.Data.SqlClient.SqlException (0x80131904): Incorrect syntax near '#UserIdNull'.
My assumption is that the above code should replicate this query:
SELECT *
FROM Users
WHERE NullableUserId IS NOT NULL
AND NullableUserId != ''
but it seems to be doing something closer to
SELECT *
FROM Users
WHERE NullableUserId IS NOT 'NULL'
AND NullableUserId != ''
If I change the query to
SELECT *
FROM Users
WHERE ISNULL(NullableUserId, '') != ISNULL(#UserIdNull, '')
it works fine. Unfortunately, I cannot use ISNULL in this case.
I've replicated this in SQL Server 2014 and 2016. We're using 2016 in our production environment.
The profiler reports that the following command is being run:
exec sp_executesql N'SELECT *
FROM Users
WHERE NullableUserId IS NOT #UserIdNull
AND NullableUserId != #UserIdBlank',N'#UserIdNull nvarchar(4000),#UserIdBlank nvarchar(4000)',#UserIdNull=NULL,#UserIdBlank=N''
Which makes me suspect this may be an issue with SQL Server itself?
Things I've tried (to no avail):
Casting the parameter to various nullable types
Using DBNull.Value
You can not use IS NOT and variable. You can hardcode NullableUserId IS NOT NULL if you always expect null.
Or create query text using some string concatenation
IS NOT #UserIdNull genuinely isn't valid SQL syntax.... IS NOT NULL is fine. This isn't a dapper issue - this is simply an SQL feature: you need to write legal SQL.
My assumption is that the above code should replicate this query:
Nope. It uses parameters. The syntax is retained. Dapper does not inject literals. This is very deliberate and correct. I wrote about this yesterday, as it happens.
You cannot use IS NOT and parameter in sp_executesql or anywhere else.
Look at this example.
This query returns 4 records from my table :
exec sp_executesql
N'SELECT * FROM tblUser WHERE gsm IS NOT null AND gsm != '''''
So now I try it with parameters for both values, and now I get an error
exec sp_executesql
N'SELECT * FROM tblUser WHERE gsm IS NOT #UserIdNull AND gsm <> #UserIdBlank',
N'#UserIdNull nvarchar(100),#UserIdBlank nvarchar(100)',
#UserIdNull=NULL,#UserIdBlank=N''
but now I get the error
Incorrect syntax near '#UserIdNull'
It will give the same error when you do it without sp_executesql
declare #UserIdNull nvarchar(100) = null
declare #UserIdBlank nvarchar(100) = ''
SELECT * FROM tblUser WHERE gsm IS NOT #UserIdNull AND gsm <> #UserIdBlank
This produces the same error
So the only option you have is to build your query without a parameter for the IS NOT value or use ISNULL()
In the query you build in your question, you known when to write IS NOT and then followed by a parameter.
I suggest to simply write IS NOT NULL in stead of using a parameter there

What is wrong with my CREATE TABLE MySQL syntax?

I am having some trouble with the CREATE IF NOT EXISTS clause.
I am using a C# application to create a MySQL table, the connection to DB has been established so it's not a problem.
The error I am getting is an exception when I try to execute the query, I get the message:
MySql.Data.MySqlClient.MySqlException (0x80004005): You have an error
in your SQL syntax; check the manual that corresponds to your MySQL
server version for the right syntax to use near 'IF NOT EXISTS(price
VARCHAR, time VARCHAR)' at line 1
In debug mode, the immediate window shows my command string as:
CREATE TABLE ticks_14_11_2016 IF NOT EXISTS(price VARCHAR, time
VARCHAR)
From the examples I have seen, this should be the proper syntax. I am not worried about constraints and keys for the time being, I just need the query to execute...
Also, here is the C# code which I use to build the string and execute query:
string tableName = "ticks_" + getTodayString();
if (databaseClient.IsConnect()) {
string tableString = "CREATE TABLE " + tableName +
" IF NOT EXISTS" +
"(price VARCHAR, " +
"time VARCHAR)";
try
{
var command = databaseClient.Connection.CreateCommand();
command.CommandText = tableString;
command.ExecuteNonQuery();
} catch (Exception e)
{
Console.WriteLine(e);
}
}
The variable databaseClient has a member that is the MySQLConnection object
Also, my server version is: 5.6.28-76.1
You have the if not exists in the wrong place, and also, the varchar type needs a mandatory length argument.
A corrected version should be:
CREATE TABLE IF NOT EXISTS ticks_XXXXX (price VARCHAR(10), time VARCHAR(10));
Change the length to whatever is appropriate for you.
For more information see the reference manual.
You have other ways also to check whether table exists in database or not.
IF OBJECT_ID(N'dbo.ticks_14_11_2016', N'U') IS NOT NULL
BEGIN
------Exists
END
IF EXISTS(SELECT 1 FROM sys.Objects WHERE Object_id =
OBJECT_ID(N'dbo.ticks_14_11_2016') AND Type = N'U')
BEGIN
------Exists
END
IF EXISTS(SELECT 1 FROM sys.Tables WHERE Name = N'ticks_14_11_2016 ' AND Type = N'U')
BEGIN
----Exists
END
IF OBJECT_ID('ticks_14_11_2016') IS NOT NULL
BEGIN
-----Exists
END
Use your logic accordingly

C# Select Query Failed with no errors

I'm having trouble with a simple SELECT query, I cannot see why it isn't working.
Here is the code:
conn.Open();
string GetPayrollQuery = "SELECT PayrollNo FROM [Employee] WHERE (FirstName + ' ' + LastName) = #Name";
OleDbCommand GetPayroll = new OleDbCommand(GetPayrollQuery, conn);
GetPayroll.Parameters.AddWithValue("#Name", OleDbType.VarChar).Value = cbbEmployees.Text;
var GotPayroll = GetPayroll.ExecuteNonQuery();
MessageBox.Show(GotPayroll.ToString());
return Convert.ToInt32(GotPayroll);
The code runs fine however it isn't extracting the data. Can anyone see why this would be?
I bet #name is coming as "MikeSmith" instead of "Mike Smith".
3 things:
try to open SQL profiler and check what you are executing on database
check database collation, is it case sensitive?
remove executenonquery (it's must used with update, delete, not select) and try executescalar (if one result for one row is exptected, otherwise try to fill a datatable or use datareader)
Make sure the same query runs in SQL using those parameter values.
Change GetPayroll.ExecuteNonQuery() to GetPayroll.ExecuteScalar() so to return a single result.
Change GetPayroll.Parameters.AddWithValue("#Name", OleDbType.VarChar).Value = cbbEmployees.Text; to GetPayroll.Parameters.AddWithValue("#Name", cbbEmployees.Text);
Use cbbEmployees.SelectedText. Fixes the problem.

I am getting the "Must declare the scalar variable "#Val1"" error when inserting the record using C#

When I am running the following code
if (NewButtonClicked == true) {
string sql = "SELECT MAX(location_id)+1 FROM locations";
OdbcCommand my_odbc_cmd = new OdbcCommand(sql, my_odbc_connection);
OdbcDataReader my_data_reader;
int new_id = 0;
my_data_reader = my_odbc_cmd.ExecuteReader();
if (my_data_reader.HasRows)
{
my_data_reader.Read();
new_id = (int)my_data_reader[0];
}
my_data_reader.Close();
textBoxLocationID.Text = new_id.ToString();
sql = "INSERT INTO locations (location_id,location,latitude,longitude,city,"
+ "state_province,country,continent) VALUES (#Val1,'#Val2',#Val3,#Val4,'#Val5','#Val6','#Val7','#Val8')";
my_odbc_cmd.Connection = my_odbc_connection;
my_odbc_cmd.CommandText = sql;
my_odbc_cmd.Parameters.AddWithValue("#Val1", new_id);
my_odbc_cmd.Parameters.AddWithValue("#Val2", textBoxName.Text);
my_odbc_cmd.Parameters.AddWithValue("#Val3", textBoxLatitude.Text);
my_odbc_cmd.Parameters.AddWithValue("#Val4", textBoxLongitude.Text);
my_odbc_cmd.Parameters.AddWithValue("#Val5", textBoxCity.Text);
my_odbc_cmd.Parameters.AddWithValue("#Val6", textBoxState_Province.Text);
my_odbc_cmd.Parameters.AddWithValue("#Val7", textBoxCountry.Text);
my_odbc_cmd.Parameters.AddWithValue("#Val8", textBoxContinent.Text);
my_odbc_cmd.CommandType = CommandType.Text;
my_odbc_cmd.ExecuteNonQuery();
}
It is giving me "Must declare the scalar variable "#Val1"" when the execution is reached at:
my_odbc_cmd.ExecuteNonQuery();
How can I solve this error. Can anyone help me? Database used at the backend is SQL Server 2008 R2. I am using the ODBC connection to connect to the database.
This probably means that new_id is null. Parameters with a value of null are not sent. You need to pass DBNull.Value instead. Crazy but true.
my_odbc_cmd.Parameters.AddWithValue("#Val1", ((object)new_id) ?? DBNull.Value);
Also: '#Val2' (and similar) are very wrong. You almost certainly mean just #Val2, no quotes.
According to the "Working with Parameter Placeholders" section on the MSDN page Configuring Parameters and Parameter Data Types, the Odbc datasource supports only positional parameters via ? in the query text, not named parameters (such as #Val1), which are supported only by SqlClient.
Additionally as Marc Gravell indicates, you shouldn't be quoting the parameters in your query.
Try changing your SQL to:
sql = "INSERT INTO locations (location_id,location,latitude,longitude,city,"
+ "state_province,country,continent) VALUES (?,?,?,?,?,?,?,?)";

Add parameter issue for fulltext search in C#

I have this part of code
string query = "SELECT ID, COL1 FROM TABLE1 WHERE CONTAINS(COL1,#text)";
sqlCommand.CommandText = sql;
sqlCommand.Parameters.Add("#text", value+"*");
value is a function parameter.
For fulltext search, the sql statement must be like this:
SELECT ID, COL1 FROM TABLE1 WHERE CONTAINS(COL1,'"eng*"')
It could search strings which start with "eng" -> english, bla blah.
But executing in C# the above code then ExecuteReader() returns empty list.
#text has as value "sometext*" but I want to add ' ' characters.
I tried string query = "SELECT ID, COL1 FROM TABLE1 WHERE CONTAINS(COL1,'#text')";
but it doesn't work, returns empty list.
Why ? How do I proceed that #text parameters must include '' characters over value for search ?
Thank you
Can you try using sqlCommand.Parameters.AddWithValue("#text", value+"*");
If above doesn't work, you can use SQL Parameter and SqlDBType.
I think your SQL query is wrong. See is this post helps.
C# constructing parameter query SQL - LIKE %
Have you tried specifying the data type? I don't think you should need the quotes in the sqlcommand string.
sqlCommand.Parameters.Add("#text", SqlDbType.VarChar);
sqlCommand.Parameters["#text"].Value = value+"*";
Or SqlDbType.NVarChar.

Categories