How do you go about selecting or deleting a specific list of numbers from a table?
For example,
select * from Table where ID = 1,2,3,4,5,6
doesn't work. I would have to do where ID = 1 or ID = 2 or ID = 3 etc etc
How do you do you use a comma delineated list to select multiple values using one where clause?
select * from table where ID IN(1,2,3,4,5)
select * from table where ID IN (1,2,3,4,5,6)
Try using the in operator select * from Table where ID in (1,2,3,4,5,6)
works with delete too
you can try with
Where ID in (1,2,3)
if you are looking for dynamic query then
execute ('select * from table where ID IN (1,2,3,4,5,6)')
otherwise
select * from table where ID IN (1,2,3,4,5,6)
will do the job
SELECT * FROM myTable WHERE id BETWEEN 1 AND 6
http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#operator_between
SELECT * FROM Table WHERE Id IN (1,2,3,4,5,6)
Note that you can't insert the entire list in a parametrized query - for example, WHERE Id IN (?) with a parameter containing '1,2,3,4,5,6' will not yield the results you're after.
A nice way to avoid building your SQL string dynamically (and potentially exposing yourself to SQL Injection) is to dynamically build the number of parameters, and then concatenate them into your SQL.
A full example with Python and SQLite (although this method can be used in any language with any SQL database engine):
ids = [1, 2, 3, 4, 5, 6]
params = tuple(ids) # because sqlite wants the parameters in tuple format
paramstring = ', '.join(['?' for dummyp in ids])
# paramstring now contains '?, ?, ?, ?, ?, ?'
# - the same number of '?' as the number of ids
sql = 'SELECT * FROM Table WHERE Id IN (' + paramstring + ')'
# sql now contains 'SELECT * FROM Table WHERE Id IN (?, ?, ?, ?, ?, ?)'
conn = sqlite3.connect(':memory:')
cursor = conn.execute(sql, params)
# You can now iterate through the cursor to get your data
Related
I am trying to execute a merge statement against an Informix database as follows:
MERGE INTO aa_rec AS dest
USING (SELECT '123456' AS id, '111-222-3333' as phone, '' as phone_ext, 'CELL' as aa FROM sysmaster:'informix'.sysdual) AS src
ON dest.id = src.id AND dest.aa = src.aa
WHEN NOT MATCHED THEN
INSERT (dest.id, dest.aa, dest.beg_date, dest.phone, dest.phone_ext, dest.ofc_add_by)
VALUES (src.id, src.aa, TODAY, src.phone, src.phone_ext, 'TEST')
WHEN MATCHED THEN UPDATE SET
dest.phone = src.phone,
dest.phone_ext = src.phone_ext,
dest.beg_date = '10/29/2019',
dest.ofc_add_by = 'TEST'
This statement works as is, with hard-coded values, but I would like to pass parameters for the values in the source table:
USING (SELECT ? AS id, ? as phone, ? as phone_ext, 'CELL' as aa FROM sysmaster:'informix'.sysdual) AS src
When I execute the statement with parameters and valid values, I receive this error:
E42000: (-201) A syntax error has occurred.
Are parameters supported in the source part of the MERGE statement? If they are, where is the error in my syntax?
For context, I'm calling this from ASP.NET using the OleDb provider for Informix.
You have:
SELECT ? AS id, ? as phone, ? as phone_ext, 'CELL' as aa FROM sysmaster:'informix'.sysdual
You can't use placeholders (? symbols) for 'structural' elements of a SELECT statement. You can't provide column names in the placeholders. And passing numbers etc as values via placeholders in the select-list doesn't work either.
I'd probably create a temp table of the appropriate shape, and insert a row into that, and then use the temp table in the select statement:
SELECT '123456' AS id, '111-222-3333' AS phone, '' AS phone_ext, 'CELL' AS aa
FROM sysmaster:'informix'.sysdual
INTO TEMP phone_data;
MERGE INTO aa_rec AS dest
USING (SELECT * FROM phone_data) AS src
ON dest.id = src.id AND dest.aa = src.aa
WHEN NOT MATCHED THEN
INSERT (dest.id, dest.aa, dest.beg_date, dest.phone, dest.phone_ext, dest.ofc_add_by)
VALUES (src.id, src.aa, TODAY, src.phone, src.phone_ext, 'TEST')
WHEN MATCHED THEN UPDATE SET
dest.phone = src.phone,
dest.phone_ext = src.phone_ext,
dest.beg_date = '10/29/2019',
dest.ofc_add_by = 'TEST'
;
DROP TABLE phone_data;
It might be better/safer to create the temp table explicitly rather than to use the INTO TEMP clause. The types are not necessarily what you'd expect (CHAR(6), CHAR(12), VARCHAR(1), CHAR(4)) — though that may not matter.
Clearly, once the temp table exists, you can insert whatever data is appropriate into the temp table using any mechanism that's available:
INSERT INTO phone_data(id, phone, phone_ext, aa) VALUES(?, ?, ?, ?)
Remember that temp tables are private to a session — you can have lots of people all using the same temporary table name at the same time without interfering with each other.
could u please correct this sqlserver query :
select * from messages where #DepartID In(MsgTo)
#DepartID is a session variable that contains the Department ID.
MsgTo is a column in messages table that contains list of values , ex. : '12','10','13','25' .. etc
i used this code :
cmd.CommandText = "select * from messages where #DepartID IN(MsgTo)"
cmd.Parameters.AddWithValue("#DepartID ", session("DepartID")) ' = 12 for example
Dim da As New SqlDataAdapter(cmd)
Dim dt As New DataTable
da.Fill(dt)
lbmsg.text = dt.Rows.Count.ToString ' returns 0 rows
sorry for my poor english
I think you're just having some syntax trouble. Have you declared the #DepartID variable in SQL? You need to make a comparison to an existing column in your WHERE clause. Like:
SELECT [ColumnName]
FROM [Table]
WHERE [ColumnName] = Value
If your department ID is a text-type column in SQL, you'll have to use single quotes on your input. You can use single quotes anyways in integers like IDs when you query them with an "IN" statement and it will work anyways. Try this:
SELECT *
FROM [messages]
WHERE [MsgTo] = #DepartID
So if you replace your #DepartID variable out with your value and then execute the statement, it will return all information for each row where your [MsgTo] column equals your #DepartID.
If you are passing multiple #DepartIDs, then you would have to pass a comma-delimited text list to the "IN" clause with your variable like the example below:
SELECT *
FROM [messages]
WHERE [MsgTo] IN ('1','5','3','12','30')
--Example where #DepartID = '1','5','3','12','30'
I'm not sure what language you're using to execute the SQL, but if this doesn't work, try encapsulating your SQL statement within an EXEC() like below:
EXEC(
SELECT *
FROM [messages]
WHERE [MsgTo] = #DepartID
)
If your MsgTo column contains a string list of values and you want to search through it for a single #DepartID, then use this code:
DECLARE #DepartID as INT; SET #DepartID = 12; --Hard coded example
SELECT *
FROM [messages]
WHERE [MsgTo] LIKE ('%,'''+#DepartID+''',%')
I have a table which contains the where selection. For example ExpressionTable:
ID WhereCase
------------------
1 = 4
2 in(2,3)
3 = 3
4 in(4,5,6)
Now I need to select from another table with this WhereCase.
Select * from tablexy join ExpressionTable as et on tablexy.ID = et.ID
Where Country (this (WhereCase) from the ExpressionTable)
When I write where Country = et.WhereCase is not working...
What is the best way for this?
What is the best way for this...
Don't do it.
Based on the example expressions you have provided you can easily store this information in a relational format that can then be joined onto (or appended onto the query with an EXISTS clause to keep the same semantics with respect to Duplicates).
CREATE TABLE XyCountries
(
XyID INT,
Country INT
);
INSERT INTO XyCountries
VALUES (1,4),
(2,2),
(2,3),
(3,3),
(4,4),
(4,5),
(4,6);
you cant have dynamic query conditions.
The only way to achieve what you want is to use dynamic SQL where you build your query in a string and them execute it like EXEC ('select 1')
You will need to build a SQL statement using Dynamic SQL and then execute it, eg
DECLARE #SQL VARCHAR(MAX)
SELECT #SQL = 'Select * from tablexy Where Country ' + et.WhereCase FROM ExpressionTable WHERE ID = ?
Then execute:
EXEC(#SQL)
I have a table as:
CREATE TABLE tbl_temp (id serial, friend_id int, name varchar(32));
I wish I could run the following SQL:
PREPARE x AS SELECT {$1,friend_id} FROM tbl_temp WHERE id = ANY($2);
EXECUTE x(33, ARRAY[1,2,3,4])
I basically looking for a statement that will return me an array of two ints first of which will be user input and second will be from table column like friend_id.
Is it really possible in PostgreSQL?
The results from SELECT ($1, friend_id) FROM tbl_temp;
EXECUTE x(44);
row
--------
(44,1)
(44,2)
(44,3)
(3 rows)
If I use PQgetvalue(PGres, 0, 0) how will the result look like: {44,45} or like (44,45)?
I think you want to use the array constructor syntax:
SELECT ARRAY[$1, friend_id] FROM tbl_temp WHERE id = ANY($2)
i'm not sure i understand what you want...
to return an array, do this.
SELECT (44, "friend_id") FROM "tbl_temp" WHERE id = ANY(ARRAY[1,2,3,4]);
My table has a large number of columns. I have a command to copy some data - think of it as cloning a product - but as the columns may change in the future, I would like to only select everything from the table and only change the value of one column without having to refer to the rest.
Eg instead of:
INSERT INTO MYTABLE (
SELECT NEW_ID, COLUMN_1, COLUMN_2, COLUMN_3, etc
FROM MYTABLE)
I would like something resembling
INSERT INTO MYTABLE (
SELECT * {update this, set ID = NEW_ID}
FROM MYTABLE)
Is there a simple way to do this?
This is a DB2 database on an iSeries, but answers for any platform are welcome.
You could do this:
create table mytable_copy as select * from mytable;
update mytable_copy set id=new_id;
insert into mytable select * from mytable_copy;
drop table mytable_copy;
I don't think this is doable entirely within SQL without going to the trouble of creating a temp table. Doing it in memory should be much faster. Beware if you go the temporary table route that you must choose a unique name for your table for each function invocation to avoid the race condition where your code runs twice at the same time and mangles two rows of data into one temp table.
I don't know what kind of language you're using but it should be possible to obtain a list of fields in your program. I would do it like this:
array_of_field_names = conn->get_field__list;
array_of_row_values = conn->execute ("SELECT... ");
array_of_row_values ["ID"] = new_id_value
insert_query_string = "construct insert query string from list of field names and values";
conn->execute (insert_query_string);
Then you can encapsulate that as a function and just call it specifying table, old id and new id and it'd work it's magic.
In Perl code the following snippet would do:
$table_name = "MYTABLE";
$field_name = "ID";
$existing_field_value = "100";
$new_field_value = "101";
my $q = $dbh->prepare ("SELECT * FROM $table_name WHERE $field_name=?");
$q->execute ($existing_field_value);
my $rowdata = $q->fetchrow_hashref; # includes field names
$rowdata->{$field_name} = $new_field_value;
my $insq = $dbh->prepare ("INSERT INTO $table_name (" . join (", ", keys %$rowdata) .
") VALUES (" . join (", ", map { "?" } keys %$rowdata) . ");";
$insq->execute (values %$rowdata);
Hope this helps.
Ok, try this:
declare #othercols nvarchar(max);
declare #qry nvarchar(max);
select #othercols = (
select ', ' + quotename(name)
from sys.columns
where object_id = object_id('tableA')
and name <> 'Field3'
and is_identity = 0
for xml path(''));
select #qry = 'insert mynewtable (changingcol' + #othercols + ') select newval' + #othercols;
exec sp_executesql #qry;
Before you run the "sp_executesql" line, please do "select #qry" to see what the command is that you're going to run.
And of course, you may want to stick this in a stored procedure and pass in a variable instead of the 'Field3' bit.
Rob
Your example should almost work.
Just add the column names of the new table to it.
INSERT INTO MYTABLE
(id, col1, col2)
SELECT new_id,col1, col2
FROM TABLE2
WHERE ...;
i've never worked with db2 but in mssql you could solve it with following procedure. this solution only works if you dont care what new id the items get.
1.) create new table with same scheme but where the id column incrementes automatically. (mssql "identitity specification = 1, identity increment = 1)
2.) than a simple
insert into newTable(col1, col2, col3)
select (col1, col2, col3) from oldatable
should be enough, be sure not to include your id colum in the above statement