What does a question mark represent in SQL queries? - sql

While going through some SQL books I found that examples tend to use question marks (?) in their queries. What does it represent?

What you are seeing is a parameterized query. They are frequently used when executing dynamic SQL from a program.
For example, instead of writing this (note: pseudocode):
ODBCCommand cmd = new ODBCCommand("SELECT thingA FROM tableA WHERE thingB = 7")
result = cmd.Execute()
You write this:
ODBCCommand cmd = new ODBCCommand("SELECT thingA FROM tableA WHERE thingB = ?")
cmd.Parameters.Add(7)
result = cmd.Execute()
This has many advantages, as is probably obvious. One of the most important: the library functions which parse your parameters are clever, and ensure that strings are escaped properly. For example, if you write this:
string s = getStudentName()
cmd.CommandText = "SELECT * FROM students WHERE (name = '" + s + "')"
cmd.Execute()
What happens when the user enters this?
Robert'); DROP TABLE students; --
(Answer is here)
Write this instead:
s = getStudentName()
cmd.CommandText = "SELECT * FROM students WHERE name = ?"
cmd.Parameters.Add(s)
cmd.Execute()
Then the library will sanitize the input, producing this:
"SELECT * FROM students where name = 'Robert''); DROP TABLE students; --'"
Not all DBMS's use ?. MS SQL uses named parameters, which I consider a huge improvement:
cmd.Text = "SELECT thingA FROM tableA WHERE thingB = #varname"
cmd.Parameters.AddWithValue("#varname", 7)
result = cmd.Execute()

The ? is an unnamed parameter which can be filled in by a program running the query to avoid SQL injection.

The ? is to allow Parameterized Query. These parameterized query is to allow type-specific value when replacing the ? with their respective value.
That's all to it.
There are several reasons why it's good practice to use Parameterized Queries. In essence, it's easier to read and debug, and circumvents SQL injection attacks.

It's a parameter. You can specify it when executing query.

I don't think that has any meaning in SQL. You might be looking at Prepared Statements in JDBC or something. In that case, the question marks are placeholders for parameters to the statement.

It normally represents a parameter to be supplied by client.

Related

SQL WHERE column = everything (with Active Record)

In SQL you can create a dynamic SQL statement when the list of conditions (WHERE) is not known in advance, but is built at code execution. So sometimes I would like a subset of records (like ids matching an array), but in other cases I don't want the condition to be applied (hence return the whole list).
In pure SQL there is this solution:Stackoverflow: SQL WHERE column = everything
SELECT * FROM table WHERE id = id
More here: Stackoverflow: Why would someone use WHERE 1=1 AND in a SQL clause?
How would I do this using the DSL from Active Record?
Both of these will work: (as will many more)
.where(MyModel.arel_attribut(:id).eq(MyModel.arel_attribute(:id)))
# OR
.where(Arel.sql("1=1"))
This "always true" type conditioning was generally used for query assembly in Stored Procedures or in String concatenation where you would always have a WHERE clause but then may not have any conditions e.g.
SET #sqlString = 'SELECT * FROM table WHERE 1=1'
IF (#var IS NOT NULL)
SET #sqlString = #sqlString + ' AND "column" LIKE ''%' + #var + '%'' '
EXEC (#sqlString)
# OR
sqlString = "SELECT * FROM table WHERE 1=1"
if someCondition
sqlString = sqlString + " AND column = " + value
end if
but all of this seems antiquated (especially in regards to Rails).
ActiveRecord avoids all of this by using a library called Arel which assembles the SQL just prior to execution.
ActiveRecord provides a convenience method (#all) to generate a similar concept of select everything. You can just call MyModel.all which will return a chainable ActiveRecord::Relation you can then apply conditions, or not, you can add ORDER BY, GROUP BY, LIMIT, HAVING, etc. statements, it is up to you in code and at runtime.
You can utilize this chainability to "assemble" these conditions as you see fit e.g.
q = MyModel.all
q.where!(name: "engineersmnky") if find_my_name?
These calls do not even have to make "logical" sense in SQL statement order because Arel knows the order in which to assemble these statements in order to form a coherent query. e.g.
MyModel.having("COUNT(column) > 1")
.order(:name)
.group(:name)
.select("name, COUNT(column) AS counter")
.where(x: 12)
.limit(2)
This is completely jumbled from a SQL standpoint but when the actual query is assembled it will be ordered correctly.
Chaining where clauses in Rails is quite easy
dataset = User.all
dataset = dataset.where(name: "John") if filter_name?
dataset = dataset.where("age > ?", 20) if filter_age?
dataset

USE WHERE 1=1 SQL [duplicate]

Why would someone use WHERE 1=1 AND <conditions> in a SQL clause (Either SQL obtained through concatenated strings, either view definition)
I've seen somewhere that this would be used to protect against SQL Injection, but it seems very weird.
If there is injection WHERE 1 = 1 AND injected OR 1=1 would have the same result as injected OR 1=1.
Later edit: What about the usage in a view definition?
Thank you for your answers.
Still,
I don't understand why would someone use this construction for defining a view, or use it inside a stored procedure.
Take this for example:
CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1 AND table.Field=Value
If the list of conditions is not known at compile time and is instead built at run time, you don't have to worry about whether you have one or more than one condition. You can generate them all like:
and <condition>
and concatenate them all together. With the 1=1 at the start, the initial and has something to associate with.
I've never seen this used for any kind of injection protection, as you say it doesn't seem like it would help much. I have seen it used as an implementation convenience. The SQL query engine will end up ignoring the 1=1 so it should have no performance impact.
Just adding a example code to Greg's answer:
dim sqlstmt as new StringBuilder
sqlstmt.add("SELECT * FROM Products")
sqlstmt.add(" WHERE 1=1")
''// From now on you don't have to worry if you must
''// append AND or WHERE because you know the WHERE is there
If ProductCategoryID <> 0 then
sqlstmt.AppendFormat(" AND ProductCategoryID = {0}", trim(ProductCategoryID))
end if
If MinimunPrice > 0 then
sqlstmt.AppendFormat(" AND Price >= {0}", trim(MinimunPrice))
end if
I've seen it used when the number of conditions can be variable.
You can concatenate conditions using an " AND " string. Then, instead of counting the number of conditions you're passing in, you place a "WHERE 1=1" at the end of your stock SQL statement and throw on the concatenated conditions.
Basically, it saves you having to do a test for conditions and then add a "WHERE" string before them.
Seems like a lazy way to always know that your WHERE clause is already defined and allow you to keep adding conditions without having to check if it is the first one.
Indirectly Relevant: when 1=2 is used:
CREATE TABLE New_table_name
as
select *
FROM Old_table_name
WHERE 1 = 2;
this will create a new table with same schema as old table. (Very handy if you want to load some data for compares)
I found this pattern useful when I'm testing or double checking things on the database, so I can very quickly comment other conditions:
CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1
AND Table.Field=Value
AND Table.IsValid=true
turns into:
CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1
--AND Table.Field=Value
--AND Table.IsValid=true
1 = 1 expression is commonly used in generated sql code. This expression can simplify sql generating code reducing number of conditional statements.
Actually, I've seen this sort of thing used in BIRT reports. The query passed to the BIRT runtime is of the form:
select a,b,c from t where a = ?
and the '?' is replaced at runtime by an actual parameter value selected from a drop-down box. The choices in the drop-down are given by:
select distinct a from t
union all
select '*' from sysibm.sysdummy1
so that you get all possible values plus "*". If the user selects "*" from the drop down box (meaning all values of a should be selected), the query has to be modified (by Javascript) before being run.
Since the "?" is a positional parameter and MUST remain there for other things to work, the Javascript modifies the query to be:
select a,b,c from t where ((a = ?) or (1==1))
That basically removes the effect of the where clause while still leaving the positional parameter in place.
I've also seen the AND case used by lazy coders whilst dynamically creating an SQL query.
Say you have to dynamically create a query that starts with select * from t and checks:
the name is Bob; and
the salary is > $20,000
some people would add the first with a WHERE and subsequent ones with an AND thus:
select * from t where name = 'Bob' and salary > 20000
Lazy programmers (and that's not necessarily a bad trait) wouldn't distinguish between the added conditions, they'd start with select * from t where 1=1 and just add AND clauses after that.
select * from t where 1=1 and name = 'Bob' and salary > 20000
where 1=0, This is done to check if the table exists. Don't know why 1=1 is used.
While I can see that 1=1 would be useful for generated SQL, a technique I use in PHP is to create an array of clauses and then do
implode (" AND ", $clauses);
thus avoiding the problem of having a leading or trailing AND. Obviously this is only useful if you know that you are going to have at least one clause!
Here's a closely related example: using a SQL MERGE statement to update the target tabled using all values from the source table where there is no common attribute on which to join on e.g.
MERGE INTO Circles
USING
(
SELECT pi
FROM Constants
) AS SourceTable
ON 1 = 1
WHEN MATCHED THEN
UPDATE
SET circumference = 2 * SourceTable.pi * radius;
If you came here searching for WHERE 1, note that WHERE 1 and WHERE 1=1 are identical. WHERE 1 is used rarely because some database systems reject it considering WHERE 1 not really being boolean.
Why would someone use WHERE 1=1 AND <proper conditions>
I've seen homespun frameworks do stuff like this (blush), as this allows lazy parsing practices to be applied to both the WHERE and AND Sql keywords.
For example (I'm using C# as an example here), consider the conditional parsing of the following predicates in a Sql query string builder:
var sqlQuery = "SELECT * FROM FOOS WHERE 1 = 1"
if (shouldFilterForBars)
{
sqlQuery = sqlQuery + " AND Bars > 3";
}
if (shouldFilterForBaz)
{
sqlQuery = sqlQuery + " AND Baz < 12";
}
The "benefit" of WHERE 1 = 1 means that no special code is needed:
For AND - whether zero, one or both predicates (Bars and Baz's) should be applied, which would determine whether the first AND is required. Since we already have at least one predicate with the 1 = 1, it means AND is always OK.
For no predicates at all - In the case where there are ZERO predicates, then the WHERE must be dropped. But again, we can be lazy, because we are again guarantee of at least one predicate.
This is obviously a bad idea and would recommend using an established data access framework or ORM for parsing optional and conditional predicates in this way.
Having review all the answers i decided to perform some experiment like
SELECT
*
FROM MyTable
WHERE 1=1
Then i checked with other numbers
WHERE 2=2
WHERE 10=10
WHERE 99=99
ect
Having done all the checks, the query run town is the same. even without the where clause. I am not a fan of the syntax
This is useful in a case where you have to use dynamic query in which in where
clause you have to append some filter options. Like if you include options 0 for status is inactive, 1 for active. Based from the options, there is only two available options(0 and 1) but if you want to display All records, it is handy to include in where close 1=1.
See below sample:
Declare #SearchValue varchar(8)
Declare #SQLQuery varchar(max) = '
Select [FirstName]
,[LastName]
,[MiddleName]
,[BirthDate]
,Case
when [Status] = 0 then ''Inactive''
when [Status] = 1 then ''Active''
end as [Status]'
Declare #SearchOption nvarchar(100)
If (#SearchValue = 'Active')
Begin
Set #SearchOption = ' Where a.[Status] = 1'
End
If (#SearchValue = 'Inactive')
Begin
Set #SearchOption = ' Where a.[Status] = 0'
End
If (#SearchValue = 'All')
Begin
Set #SearchOption = ' Where 1=1'
End
Set #SQLQuery = #SQLQuery + #SearchOption
Exec(#SQLQuery);
Saw this in production code and asked seniors for help.
Their answer:
-We use 1=1 so when we have to add a new condition we can just type
and <condition>
and get on with it.
I do this usually when I am building dynamic SQL for a report which has many dropdown values a user can select. Since the user may or may not select the values from each dropdown, we end up getting a hard time figuring out which condition was the first where clause. So we pad up the query with a where 1=1 in the end and add all where clauses after that.
Something like
select column1, column2 from my table where 1=1 {name} {age};
Then we would build the where clause like this and pass it as a parameter value
string name_whereClause= ddlName.SelectedIndex > 0 ? "AND name ='"+ ddlName.SelectedValue+ "'" : "";
As the where clause selection are unknown to us at runtime, so this helps us a great deal in finding whether to include an 'AND' or 'WHERE'.
Making "where 1=1" the standard for all your queries also makes it trivially easy to validate the sql by replacing it with where 1 = 0, handy when you have batches of commands/files.
Also makes it trivially easy to find the end of the end of the from/join section of any query. Even queries with sub-queries if properly indented.
I first came across this back with ADO and classic asp, the answer i got was: performance.
if you do a straight
Select * from tablename
and pass that in as an sql command/text you will get a noticeable performance increase with the
Where 1=1
added, it was a visible difference. something to do with table headers being returned as soon as the first condition is met, or some other craziness, anyway, it did speed things up.
Using a predicate like 1=1 is a normal hint sometimes used to force the access plan to use or not use an index scan. The reason why this is used is when you are using a multi-nested joined query with many predicates in the where clause where sometimes even using all of the indexes causes the access plan to read each table - a full table scan. This is just 1 of many hints used by DBAs to trick a dbms into using a more efficient path. Just don't throw one in; you need a dba to analyze the query since it doesn't always work.
Here is a use case... however I am not too concerned with the technicalities of why I should or not use 1 = 1.
I am writing a function, using pyodbc to retrieve some data from SQL Server. I was looking for a way to force a filler after the where keyword in my code. This was a great suggestion indeed:
if _where == '': _where = '1=1'
...
...
...
cur.execute(f'select {predicate} from {table_name} where {_where}')
The reason is because I could not implement the keyword 'where' together inside the _where clause variable. So, I think using any dummy condition that evaluates to true would do as a filler.

How to use variable (datatable) in sql command text to execute

I am new to Vertica and trying this in angular aspx page.
`con.Open();
cmd = con.CreateCommand();
cmd.Connection = con;
cmd.Parameters.Add(new VerticaParameter("#tblCustomers", table));
cmd.CommandText = "insert into customers select * from #tblCustomers";
cmd.ExecuteNonQuery();`
I have established the connection and inserted some fresh records too.
But Now I am trying to insert bulk records in my vertica database's table.
Something Same like SqlServer,
I have loaded my table data into "table" variable. Which is a datatable.
Is it possible to do like this ?? As I am getting some error
"
Incorrect syntax at or near $1"
customers and #tblCustomers both have same columns.
Thanks!
Setting aside whether or not you should do something like this, in the code that you've posted you're passing #tblCustomers as a parameter to the query, so it's going to treat it as a string value, not an object name in the query. You need to build the CommandText in your code without that as a parameter. Something like:
cmd.CommandText = "insert into customers select * from " & tableName
(Sorry if that syntax isn't quite right, but hopefully it gets across the point)
Some additional (and important) notes though:
Always use a column list when doing an INSERT. Use INSERT INTO MyTable (some_column, some_other_column) SELECT... not INSERT INTO MyTable SELECT...
NEVER use SELECT *. List out your column names.

Unable to select values when using a parameter for the column name

Try
Using connection As New SqlConnection(ConnectionString)
connection.Open()
SQL = "SELECT #PARAM FROM SystemOps"
sqlCmd = New SqlClient.SqlCommand(SQL, connection)
sqlCmd.Parameters.Add(New SqlClient.SqlParameter("#PARAM", SqlDbType.VarChar)).Value = "SystemNavn"
' .. and so on...
When I run the code, it returns with a result of "SystemNavn" (which is the name of the column in the table), instead of the value of that column in the current row. What am I doing wrong?
You cannot use parameter names for column names, or any other SQL syntax. You can only use parameters as placeholders for literal values. Parameters always get replaced with the literal form for the value, so in your example, the command which is being run, essentially, gets evaluated as:
SELECT 'SystemNavn` FROM SystemOps
In order to have a variable column name, like that, I would recommend dynamically building the SQL string, like this:
Dim columnName As String = "SystemNavn"
SQL = "SELECT [" & columnName & "] FROM SystemOps"
However, by doing so, you are opening yourself up to potential SQL-injection attacks, so you need to be careful. The safest way, that I'm aware of, to avoid an attack in a situation like this is to get the list of column names from the database and compare the columnName variable against that list to ensure that it is actually a valid column name.
Of course, if the column name never changes, then there's no reason to make it a variable at all. In that case, just hard-code it directly into the SQL command, thereby avoiding the necessity for parameters or variables at all:
SQL = "SELECT SystemNavn FROM SystemOps"
Your query doesn't need any parameters in this case. just do
SQL = "SELECT SystemNavn FROM SystemOps"
This is secure. If later you need to filter this, you can do something like:
SQL = "SELECT SystemNavn FROM SystemOps WHERE COL_A = #ColA"
FYI, for your code above, since it is a VARCHAR type, it is being executed like so:
SELECT 'SystemNavn' FROM SystemOps
That is why you're getting 'SystemNavn' back.
You cannot use a parameter to specify the name of a column or a table.
The parameters collection are used to specify the values to search for, to insert, to update or delete.
Your code should be changed to something like this
Using connection As New SqlConnection(ConnectionString)
connection.Open()
SQL = "SELECT SystemNavn, <other fiels if needed> " & _
"FROM SystemOps WHERE <keyfield_name> = #PARAM"
sqlCmd = New SqlClient.SqlCommand(SQL, connection)
sqlCmd.Parameters.AddWithValue("#PARAM", paramValue)
......
End Using
Of course the example above assumes that you have a WHERE clause, if you want to retrieve every value of the column SystemNavn without condition, then you don't need a parametrized query because every part of your sql command is provided by you and there is no worry for sql injection.

Using a query to loop through tables that are similar in structure but have different names

I would like to use a query to loop through tables that are similar in structure but have different names (ie. tableJan2011, tableFeb2011, tableMar2011 etc.)
Is there a way in MS Access and in SQL Server to use the same query statement while varying the table name within it. (similar to using parameter values) (need this to add different input to each different month's table)
This is a bad table design. You should have a singe table, where you have a column(s) to indicate month/year. You would then just query this single table and add a WHERE month='X' and YEAR='Y' to limit your results to what you need.
without a table redesign use UNION and clever WHERE clause parameters, which will cause rows to only come from the table that applies.
SELECT
..
FROM tableJan2011
where...
UNION
SELECT
..
FROM tableFeb2011
where...
UNION
SELECT
..
FROM tableMar2011
where...
First off, listen to the people who are telling you to use one table. They know of which they speak.
If you can't do that for some obscure reason (such as inheriting the design & not being allowed to change it), then you're stuck writing VBA code. There's no way that I know of, in Access, to substitute source tables (or even source columns--values only), in a saved QueryDef.
You'll need something like this:
Private Function QueryTable (strTableName as String) As DAO.Recordset
Const theQuery as String = "SELECT tbl.* FROM [table] As tbl"
Dim sSql As String
Dim db As DAO.Database
Dim rs As DAO.Recordset
sSql = Replace(theQuery, "[table]", strTableName)
Set db = CurrentDb()
Set rs = db.OpenRecordset(sSql)
Set QueryTable = rs
End Function
Note that this is simplified code. There's no error handling, I haven't released the objects (which I usually do, even though they'll go out of scope), and SELECT * is almost always a bad idea.
You'd then call this function wherever you need it, passing in the name of the table.
consider moving the year and month out of the table name and into columns in one table.
you can create a table with query or table names to use at runtime, but you have to be able to write Access BASIC code in a module.
Here's an example, assuming you have a query built on a table with the query names you want to execute:
Set db = CurrentDb
Set rsPTAppend = db.OpenRecordset("qry_PTAppend")
rsPTAppend.MoveFirst
Do Until rsPTAppend.EOF
qryPT = rsPTAppend("PT")
Set qdef = db.QueryDefs(qryPT)
sqlOld = qdef.sql
sqlNew = sqlOld
' manipulate sql
If sqlNew <> sqlOld Then
qdef.sql = sqlNew
End If
db.QueryDefs(rsPTAppend("append")).Execute
If sqlNew <> sqlOld Then
qdef.sql = sqlOld
End If
rsPTAppend.MoveNext
Loop
Don't know what is possible in Access but in SQL Server you could create a view that use union to get all tables together and then build your queries against the view.
One other option you have could be to build your queries dynamically.
In sql server you can execute a string as sql.
http://msdn.microsoft.com/en-us/library/ms175170.aspx
I'm not aware of anything similar in MS Access (though my experience is limited). You could however dynamically generate your sql in code to accomplish this. Perhaps you could create a function to take the table suffix and parameters and build the desired sql that way.