Same query showing different result when used as string in C# - c#

SQL Query
SELECT [ServerName]+ '\' + PARSENAME(REPLACE([Instance],'\','.'), 1) AS SIN,DATE FROM [DBReports].[dbo].[Accesslevelreport]
C# query
"SELECT [ServerName]+ '\' + PARSENAME(REPLACE([Instance],'\','.'), 1) AS SIN,DATE FROM [DBReports].[dbo].[Accesslevelreport]";
I want to convert it in C# but results are different as compared to running in SQL
Results from SQL= ANDSQLP47\DWMOD
Results from C#= ANDSQLP47ANDSQLP47\DWMOD
Expected Result
Data in [ServerName]= ANDSQLP47
Data in [Instance] =ANDSQLP47\DWMOD
SIN column will contain the Server Name and Instance Name, separated with a backslash ('\'). If the
instance field read from the database contains a slash in the text ('\'), remove
the slash and everything to the left of it before combining the fields for the
SIN column of the spreadsheet (only truncate this for processing - nothing
changes in the database).
For example : If the instance field contains
'ANDSQLP47\CTOPROD8R2', then truncate that to 'CTOPROD8R2' before
combining it with the ServerName field.

Just escape your query.
var query = #"SELECT [ServerName]\PARSENAME(REPLACE([Instance],'\','.'), 1) AS SIN,DATE" +
"FROM [DBReports].[dbo].[Accesslevelreport]";
or
var query = #"
SELECT [ServerName]\PARSENAME(REPLACE([Instance],'\','.'), 1) AS SIN, DATE
FROM [DBReports].[dbo].[Accesslevelreport]
";

Related

MySQL filter by date

I am building a query string like this.
string query = "SELECT * FROM " + table + " where DATE(Date) > " + howFarBack.ToString("yyyy-MM-dd");
Hwowever, when it executes
while (dataReader.Read())
I am seeing Dates well before the howFarBack ????
public List<OHLC> Select(string table, System.DateTime howFarBack)
{
string query = "SELECT * FROM " + table + " where DATE(Date) > " + howFarBack.ToString("yyyy-MM-dd");
//Create a list to store the result
var list = new List<OHLC>();
//Open connection
if (OpenConnection() == true)
{
//Create Command
MySqlCommand cmd = new MySqlCommand(query, connection);
//Create a data reader and Execute the command
MySqlDataReader dataReader = cmd.ExecuteReader();
//Read the data and store them in the list
while (dataReader.Read())
{
var ohlc = new OHLC();
ohlc.Date = (System.DateTime)dataReader[0];
ohlc.Open = Math.Round((double)dataReader[1], 2);
When in doubt, try to debug by examining the resulting SQL query, not the C# code that formats the SQL query.
I would guess that your query lacks single-quote delimiters around the date literal. So it is ultimately a query like:
SELECT * FROM MyTable where DATE(Date) > 2021-11-02
But 2021-11-02 isn't a date, it's an arithmetic expression that evaluates to an integer: 2021 minus 11 minus 2 = 2008. This will certainly match a lot of dates you didn't intend it to.
You could solve this by ensuring that the right type of quotes are around your date literal (it's actually a string literal that is interpreted as a date when compared to a date).
SELECT * FROM MyTable where DATE(Date) > '2021-11-02'
But it's far better to use query parameters, as mentioned in the comment above.
SELECT * FROM MyTable where DATE(Date) > #howFarBack
Then you don't need quotes. In fact you must not use quotes around the parameter placeholder.
See Parameterized Query for MySQL with C# or many other references for using parameters in SQL statements in C#.
Also remember that parameters can only be used in place of a single literal value. You can't use parameters for table or column identifiers, or a list of values, or SQL keywords, etc.

SQL Command c# not getting the right results

I'm running the following query
cmd = new SqlCommand("SELECT * FROM addresses WHERE identifier NOT IN(#notIn)", _connector.getMsConnection());
When I view the value notIn and copy this query I get an empty result on my database (which I'm expecting). However when I'm running this code I get 6 results. The content of string notIN is for example
string notIn = "'201619011124027899693E8M2S3WOCKT9G6KHE11' ,'201619011124027899693E8M2S3WOCKT9G6KHE12'"
which combined with
SELECT *
FROM addresses
WHERE identifier NOT IN(#notIn)
Should create
SELECT *
FROM addresses
WHERE identifier NOT IN ('201619011124027899693E8M2S3WOCKT9G6KHE11',
'201619011124027899693E8M2S3WOCKT9G6KHE12' )
which runs as expected.
it should be like this:
cmd = new SqlCommand(string.Format("SELECT * FROM addresses WHERE identifier NOT IN({0})", notIn), _connector.getMsConnection());
This way the value of notIn will be concat to your string query.
Contrary to what the other answers say, concatenating the string to build the SQL is a bad idea, especially since the input values are strings. You open yourself up to SQL injection attacks.
You should be generating multiple parameters for each item in your list.
For example, if you have the input input:
var notIn = new[] { "A1", "B2", "C3" }
You'd want something like
for(var i = 0; i < notIn.Length; i++)
command.AddParamWithValue("p"+i, notIn);
And then you can build the SQL with concatenation (note that we are not concatenating an input here)
var sql = "SELECT * FROM addresses WHERE identifier NOT IN(" + string.Join(",", notIn.Select(i,v) => { "#p" + i; }) + ")";
Which then would look like:
SELECT * FROM addresses WHERE identifier NOT IN (#p0,#p1,#p2)
Alternatively, you could dump the values into a temporary table and do a join.
Note that the above is pseudocode, and may not compile verbatim, but should give you the right idea about how to procede.
It's because, you passed the #notIn as a whole string, which means, the SQL server see it as:
SELECT * FROM addresses WHERE identifier NOT IN('''201619011124027899693E8M2S3WOCKT9G6KHE11'',''201619011124027899693E8M2S3WOCKT9G6KHE12''')
So you got empty result
Try changing the "not in" to where clause and generate the where with C#:
string selectStatement = "SELECT * FROM addresses WHERE";
selectStatement += " identifier != '201619011124027899693E8M2S3WOCKT9G6KHE11' and identifier != '201619011124027899693E8M2S3WOCKT9G6KHE12'";
Or if you really want to use parameterized SQL, try doing it in stored procedure instead.

Dynamically select data runtime from entity framework 6.0 throws exception

I would like to selected dynamic data from entity framework as per below.
if I select "Select * from TableName" in queryString it works fine but if I select only selected column/columns it does not work and throws an exception.
Working ok
string queryString = #"SELECT * FROM context.TableName ";
DbSqlQuery<SampleTable> result = context.SampleTable.SqlQuery(queryString);
Throws Exception
columnList is generated run time from SampleTable which may consists one or more columns.
string queryString = #"SELECT " + String.Join(",", columnList) + " FROM context.TableName ";
DbSqlQuery<SampleTable> result = context.SampleTable.SqlQuery(queryString);
Exception:
The data reader is incompatible with the specified 'context.TableName ... A member of the type, does not have a corresponding column in the data reader with the same name.
As per my understanding EF try to map all columns but above query does not have same number of columns as set in code and so it throws exception.
You can check the below steps :
Use the alias names of columns in your columnList (ex: tablename.Id instead of Id).
That all the column names in your columnList are mapped in the Entity.
Check that the column names in your columnList are same as of the Entity.
Hope this will help.

Varying number of records

I am executing a SQL Server stored procedure from my C# code which essentially pulls some data from a database based on the supplied condition.
DataSet GetAllxxxxxByDate(string entityValue,string companyValue)
{
using (var sqlConn = new SqlConnection(GetConnectionString()))
{
using (var cmd = new SqlCommand())
{
var data = new DataSet();
cmd.CommandText = “myStoredprodecure”;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = sqlConn;
var eVal = string.IsNullOrWhiteSpace(entityValue) ? string.Empty : entityValue;
cmd.Parameters.AddWithValue("#entity_value", eVal);
var company = string.IsNullOrWhiteSpace(companyValue) ? string.Empty : companyValue;
cmd.Parameters.AddWithValue("#company", company);
var sqlDataAdaptor = new SqlDataAdapter(cmd);
sqlDataAdaptor.Fill(data);
return data;
}
}
}
Here entityValue, companyValue are comma separated strings, formed dynamically within C# code and pass it to stored procedure.
Eg:
’first’,’second’,’third’
And the stored procedure uses these values to fill the NOT IN condition defined within it.
The issue is that, I am getting inconsistent number of records when I execute the code.
Following is a quick screenshot where first WHERE clause return 3 records and second WHERE clause return 1 record. The input values for the first WHERE clause is been filled from c# code and the second is been filled manually to test.
The only difference, which I can spot is number of quotes.
Question: can someone help me to zero in the issue or the difference in these give WHERE clause ?
Well, you don't show what entity_value is in your results, but the difference between the two is you're adding single quotes around the literal values:
N'''FSEC''' in SQL is the literal valiue 'FSEC'
'FSEC' in SQL is just FSEC (without the quotes).
My guess is that records 2004981 and 2004982 have a value of FSEC (without the quotes) for entity_value.
If you're adding parameter values from C# code, don't add quotes around them like you would if you were building a string. SQL will treat the values as strings without needing string qualifiers.
EDIT
Okay, I just read this statement:
Here entityValue, companyValue are comma separated string
You can't just pass in a comma-delimited string to an IN clause. To search for multiple values there are a few options:
Add commas to each end and use LIKE:
Where (',' + #entity_value +',' LIKE '%,' + entity_value + ',%')
Parse the string into a temporary table, than use that table in your IN clause
Pass the values as a table-valued parameter and use that in your IN clause.
Build the SQL statement as a string and execute it with EXEC

C# Sql Compact text query on binary column

I was wondering if anyone knew how to compile a text query for sql compact that goes like this :
command.CommandText = "SELECT * FROM tableName WHERE id = binary_Data"
The id column is a 32 byte binary column that is indexed and "binary_Data" is the binary data to compare to, but I am not sure how to get a "binary_Data" into the text query so sql can compare it.
The best way is to use parameters:
command.CommandText = "SELECT * FROM TableName WHERE id = #binary_data";
command.Parameters.AddWithValue("#binary_data", byteArray);
Alternatively, you could manually build a hex string prefixed with 0x to create a binary literal to append to the query but it's not recommended.

Categories