Why can you not use parameters in an SQL statement as the column name? I found that out after two hours of thinking what the problem could be. The only way it seemed possible was by doing it in a way it could be vulnerable to SQL injections (which for me wasn't a problem because the parameters are generated serverside).
This works:
string cmdgetValues = "SELECT " + column + " FROM user WHERE " + filterColumn + " = #filter";
MySqlCommand getValues = new MySqlCommand(cmdgetValues, connectionDB);
getValues.Parameters.AddWithValue("#filter", filterValue);
This doesn't work:
string cmdgetValues = "SELECT #column FROM user WHERE #filterColumn = #filter";
MySqlCommand getValues = new MySqlCommand(cmdgetValues, connectionDB);
getValues.Parameters.AddWithValue("#column", column);
getValues.Parameters.AddWithValue("#filterColumn", filterColumn);
getValues.Parameters.AddWithValue("#filter", filterValue);
Why is this? And is it intended?
Because select columns are fundamental query
You can't parameterise the fundamental query, so you have to build the query at the code.
If you want to decide the query columns runtime maybe you can try to use Prepared SQL Statement Syntax in Mysql.
Related
I am new in python as well as mysql. I am having trouble in populating proper query statement for mysql.
sql = "SELECT * FROM Persons WHERE %s"
cur = db.cursor()
cur.execute(sql,(where,))
where is a string variable which creates a string for WHERE clause; this is the point of question. When I print this variable it give the following result:
Gender = True And IsLate = False
(without any quotes) but when I add this variable to the query to execute it, it adds single quotes around the string.
I used the command
print(cur.statement)
and it prints:
SELECT * FROM Persons WHERE 'Gender = True And IsLate = False'
After supplying parameter, it puts it within single quotes and query returns 0 rows.
I have worked around by concatenating the query statement and variable together and execute the string as query, that worked,
sql = sql + where
cur.execute(sql)
But I know that is not the professional way, as I have searched and found the professional way is to use parameterized query and use variable to store the condition(s) and supplying it at the execution of query.
Looking for advice, am I thinking the right way or otherwise?
The whole point of using parameter substitution in cursor.execute() is that it protects you from SQL injection. Each parameter is treated as a literal value, not substituted into the query and re-interpreted.
If you really want it to be interprted, you need to use string formatting or concatenation, as you discovered. But then you will have to be very careful in validating the input, because the user can supply extra SQL code that you may not have expected, and cause the query to malfunction.
What you should do is build the where string and parameter list dynamically.
where = []
params = []
if gender_supplied:
where.append('gender = %s')
params.append(gender)
if islate_supplied:
where.append*('islate = %s')
params.append(islate)
sql = 'select * from persons'
if where:
query = sql + ' where ' + ' and '.join(where)
else:
query = sql
cur.execute(query, params)
I have a local SQL Server in Tabular Mode in which I read data from a local regular SQL Server Database. I have created some Calculated Columns and Fields.
Now I want to use these calculated columns and fields in my "Report Server Project"; how do I do this?
Thanks!
To query Tabular models from .NET look into using the AdomdClient namespace. The following is a simple example, which sends a DAX command to the Tabular database and returns the results for one measure filtered by the column of one of the dimensions. Calculated columns can be accessed as they typically would be using this method.
AdomdConnection conn = new AdomdConnection("Data Source=localhost;Catalog=YourTabularModel");
conn.Open();
string query = "EVALUATE SUMMARIZECOLUMNS( Employee[Employee Name], \"Employee Count\", "
+ "[Total Employee Count])";
AdomdCommand modelCmd = new AdomdCommand(query, conn);
AdomdDataReader dataRdr = modelCmd.ExecuteReader();
while (dataRdr.Read())
{
MessageBox.Show(dataRdr[0].ToString() + " - " + dataRdr[1].ToString());
}
dataRdr.Close();
conn.Close();
I am building a MySql query in vb.net:
cmd.CommandText = "Select id INTO #idDep from dBase.tableA where guid in (#strdepToDelete, #strOtherToDelete) and IsDependent = '1'; " & _
"Select id INTO #idOther from dBase.tableA where guid in (#strdepToDelete, #strOtherToDelete) and IsDependent = '0'; " & _
"delete from dBase.tableA where id in(#idDep, #idOther);"
cmd.Parameters.Add("#strdepToDelete", MySql.Data.MySqlClient.MySqlDbType.String)
cmd.Parameters("#strdepToDelete").Value = strdepToDelete
cmd.Parameters.Add("#strOtherToDelete", MySql.Data.MySqlClient.MySqlDbType.String)
cmd.Parameters("#strdepToDelete").Value = strOtherToDelete
cmd.Parameters.Add("#IdDep", MySql.Data.MySqlClient.MySqlDbType.Int24)
cmd.Parameters("#IdDep").Value = Nothing
cmd.Parameters.Add("#IdOther", MySql.Data.MySqlClient.MySqlDbType.Int24)
cmd.Parameters("#IdOther").Value = Nothing
Try
cmd.ExecuteNonQuery()
success = True
Catch ex As Exception
End Try
Return success
Error is caught which indicates that Null cannnot be #IdDep value. I have tried "" for value of that variable; I have tried ? for value of that variable. When I run the command text gained from hovering over cmd in MySql it works as it should. My question is how to paramaterize queries with nothing value.
I don't think your problem is the datatype, the command object is pretty good at inferring DBNull from Nothing. I think your SQL statement is the problem...
If you have an IN statement, FldNm IN(1,2,NULL) then the SQL engine will parse it as FldNm=1 OR FldNm=2 OR FldNm=NULL. That last item isn't valid (for SQL in general, and also for MySQL in particular ... just tried it to make verify).
You can ask for records where FldNm IS NULL, but not where FldNm=NULL.
So - when you construct that SQL statement, you'll need to skip the values in your IN clause if they are null. OR - use some non-existent value if the value is null as a "work around."
Hope that's helpful!
I am using Groovy/Grails framework, I am fetching the Bigdecimal value from the mysql DB using the
Query = "select d.quantitativeData FROM MyTable d where d.segment.id = " + segmentid +
" and d.sustainabilityIndicatorSubQuestion.id = "+questionid+" and d.tenantId= " +
TenantUtils.getCurrentTenant()+" order by d.id desc",[max:1]"
quantitativeData is a Bidgecimal variable.
But the value is retrieved from this query is like "0E-20" format, but the value in the database like '121.00000000000' , How to resolve this, can anybody help me out.
Thanks in advance.
The BigDecimal is being converted to the string "0E-20", because you're constructing the query by concatenating strings together, rather than by using ? query placeholders.
If you use placeholders instead of string concatenation it will resolve this problem and also make you immune to SQL injection attacks.
Can anyone tell me how to display all the selected value of my multi value parameter in SSRS report. When giving parameter.value option it gives error.
You can use the "Join" function to create a single string out of the array of labels, like this:
=Join(Parameters!Product.Label, ",")
=Join(Parameters!Product.Label, vbcrfl) for new line
I didn't know about the join function - Nice! I had written a function that I placed in the code section (report properties->code tab:
Public Function ShowParmValues(ByVal parm as Parameter) as string
Dim s as String
For i as integer = 0 to parm.Count-1
s &= CStr(parm.value(i)) & IIF( i < parm.Count-1, ", ","")
Next
Return s
End Function
Hopefully someone else finds this useful:
Using the Join is the best way to use a multi-value parameter. But what if you want to have an efficient 'Select All'? If there are 100s+ then the query will be very inefficient.
To solve this instead of using a SQL Query as is, change it to using an expression (click the Fx button top right) then build your query something like this (speech marks are necessary):
= "Select * from tProducts Where 1 = 1 "
IIF(Parameters!ProductID.Value(0)=-1,Nothing," And ProductID In (" & Join(Parameters!ProductID.Value,"','") & ")")
In your Parameter do the following:
SELECT -1 As ProductID, 'All' as ProductName Union All
Select
tProducts.ProductID,tProducts.ProductName
FROM
tProducts
By building the query as an expression means you can make the SQL Statement more efficient but also handle the difficulty SQL Server has with handling values in an 'In' statement.