I have this table structure and and some sample data. I want return data for multiple ids via parameter. I have declared a parameter string and now I want to compare it with the column but it ain't allowing because ID is integer.
Can anybody give me any help here ?
CREATE TABLE EMPLOYEE
(
ID INT,
EMPLOYEE_NAME VARCHAR(50)
);
INSERT INTO EMPLOYEE VALUES (1, 'Isaac Frempong');
INSERT INTO EMPLOYEE VALUES (2, 'Eric Ortizz');
DECLARE #StrID VARCHAR(20) = '1, 2'
SELECT * FROM EMPLOYEE
WHERE ID = #StrID
SELECT * FROM EMPLOYEE
WHERE #StrID+',' LIKE '%'+cast(ID as varchar(20))+'%,'
Pretty bad performance as it will need to do a table scan but safe enough.
Generally though, your list of IDs should be a table variable you can do a proper JOIN or IN with
The easiest solution is to use dynamic SQL
DECLARE #sql VARCHAR(1000) = 'SELECT * FROM EMPLOYEE WHERE ID IN (' + #StrID + ')';
EXEC(#sql);
For SQL Server 2017+ you could use STRING_SPLIT a table-valued function that splits a string into rows of substrings
CREATE TABLE EMPLOYEE
(
ID INT,
EMPLOYEE_NAME VARCHAR(50)
);
INSERT INTO EMPLOYEE VALUES (1, 'Isaac Frempong');
INSERT INTO EMPLOYEE VALUES (2, 'Eric Ortizz');
DECLARE #StrID VARCHAR(20) = '1, 2'
SELECT * FROM EMPLOYEE
WHERE ID IN (SELECT value FROM STRING_SPLIT (#StrID,','))
Refer this working fiddle
Create a user defined table type and pass it as a parameter.
CREATE TYPE [UDT_INTIDS] AS TABLE(
[ID] [int] NOT NULL
)
GO
-- create a table value
DECLARE #IDs [UDT_INTIDS];
INSERT #IDs VALUES (1),(2);
-- search using table value.
SELECT e.*
FROM EMPLOYEE e
WHERE e.ID IN (SELECT p.ID FROM #IDs p);
-- or
SELECT e.*
FROM EMPLOYEE e
JOIN #IDs p ON e.ID = p.ID;
See https://learn.microsoft.com/en-us/sql/relational-databases/tables/use-table-valued-parameters-database-engine?view=sql-server-2017 for more details.
You can use the Cast in SQL-Server to cast it to the appropriate datatype. Source Here
WHERE CAST(ID AS VARCHAR(20)) = #StrID
Alternatively: You can use CONVERT function.
WHERE CONVERT(VARCHAR(20), ID) = #StrID
Related
I have a stored procedure that takes in a table as a parameter.
For example: I have a type PartsImport:
CREATE TYPE PartsImport AS TABLE
(
Number_Key varchar(10),
LogDate smalldatetime,
FullName varchar(125),
Descrip varchar(250)
);
Then the stored procedure takes in this param:
#PTable PartsImport ReadOnly
The stored procedure does an insert into a table via a simple select * from #PTable, but now I need to join this table variable with other tables when creating the select statement, but I always get an error message
Must declare the scalar variable "#PPTable"
How do you select an individual column from this #PTable? I tried #PTable.LogDate, but it doesn't like the syntax. Is it possible to use the variable table in a join and select the columns or does it only work with select * ?
You can try using an Alias to refer to your table, instead of the variable name. For example:
SELECT P.LogDate FROM #PTable AS P
try with below example, when you fetch column only from table variable then works fine but when you use in join you must use alias name with table variable name.
CREATE TYPE PartsImport AS TABLE
(
Number_Key varchar(10),
LogDate smalldatetime,
FullName varchar(125),
Descrip varchar(250)
);
create table PartsImportother (col1 varchar(10), col2 varchar(3))
insert into PartsImportother values('1','ads')
Declare #table PartsImport
insert into #table(Number_Key,LogDate,FullName,Descrip) values('1','01-01-2015','aaa','adsfadfa')
-- select [specific column] from [only table variable]
select Number_Key from #table
-- select [specific column] from [table variable with join]
select T.Number_Key from #table as T inner join PartsImportother on T.Number_Key = PartsImportother.col1
DECLARE #ID INT
SET #ID = (select top 1 USER_REQ_JOB_ID
from T8504_USER_REQ_JOB
where JOB_GRP_ID = 160
order by LST_UPDT_TS desc)
SELECT INPUT_PARM_VAL_TX
from TBL_RPT_JOB_INPUT_PARAM
where USER_REQ_JOB_ID = #ID
This returns these results:
USA
USCC
6
7
2
These five records what I get I want to assign to five different variables to use in stored procedure.
I was trying with table variable like this :
declare #CID table (
Region Char(3)
,Segment Char(3)
,MasterContractId int
,ctcid int
,templateid int)
insert into #CID (Region,Segment,MasterContractId,ctcid,templateid)
But how to insert that 5 rows here?
INSERT INTO #CID
select * from
(
select
'Temp' + convert(char(1), row_number() over (order by (select 0))) as columnName,
INPUT_PARM_VAL_TX as Value
from TBL_RPT_JOB_INPUT_PARAM where USER_REQ_JOB_ID = #ID
) d
pivot
(
max(value)
for columnname in (Temp1, Temp2, Temp3, Temp4, Temp5)
) piv;
See if this helps.
Take a look at this fiddle for an example.
Courtesy:
Add row number to this T-SQL query
Efficiently convert rows to columns in sql server
EDIT: The sql adds an extra column to generate row numbers to use it as an extra column, which is pivoted as column heading.
it's really gross, but one way you could probably do it is this (though you'll need to apply it to your case):
http://sqlfiddle.com/#!6/d41d8/21507
declare #table TABLE (value varchar(50))
INSERT INTO #table
VALUES ('first')
INSERT INTO #table
VALUES ('second')
INSERT INTO #table
VALUES (3)
INSERT INTO #table
VALUES (4)
DECLARE #temp TABLE (id int identity(1,1), value varchar(50))
INSERT INTO #temp
SELECT [value]
FROM #table t
SELECT *
FROM #temp
DECLARE #CID TABLE (Region varchar(50), cont varchar(50), another int, andAnother int)
INSERT INTO #CID
(
Region,
cont,
another,
andAnother
)
VALUES
(
(SELECT value FROM #temp WHERE id = 1), -- Region - varchar
(SELECT value FROM #temp WHERE id = 2), -- cont - varchar
(SELECT value FROM #temp WHERE id = 3), -- another - int
(SELECT value FROM #temp WHERE id = 4) -- andAnother - int
)
SELECT * FROM #cid
note that i assumed you're using mssql, you did not specify
This question already has answers here:
Parameterize an SQL IN clause
(41 answers)
Closed 8 years ago.
In my table id column's datatype is int.
And I have a list of items' ids to be selected.
So, here is some piece of my code:
DECLARE #user_list
SELECT #user_list=(
SELECT user_list
FROM sometable
WHERE rowNum=xxx
);
SELECT *
FROM anotherTable
WHERE user_id IN(#user_list)
but it doesn't work, the error msg like :
can't convert varchar to int
Thanks!
You can Create a Split function and that will be use when you want.
CREATE FUNCTION [dbo].[Split]
(
#List nvarchar(max),
#SplitOn nvarchar(1)
)
RETURNS #RtnValue table (
Id int identity(1,1),
Value nvarchar(max)
)
AS
BEGIN
While (Charindex(#SplitOn,#List)>0)
Begin
Insert Into #RtnValue (value)
Select
Value = ltrim(rtrim(Substring(#List,1,Charindex(#SplitOn,#List)-1)))
Set #List = Substring(#List,Charindex(#SplitOn,#List)+len(#SplitOn),len(#List))
End
Insert Into #RtnValue (Value)
Select Value = ltrim(rtrim(#List))
Return
END
after that you can call the function in your query as below.
SELECT * FROM anotherTable WHERE user_id IN(dbo.split(#user_list,','))
Otherwise, you have to use dynamic query.
Just use a table variable, which allows you to add normal word into a variable:
DECLARE #user_list AS TABLE (user_id int NOT NULL);
INSERT #user_list
SELECT user_list
FROM sometable
WHERE rowNum=xxx;
SELECT *
FROM anotherTable
WHERE user_id IN (SELECT user_id FROM #user_list)
If you make #user_list a table variable, you can join or filter against it like any other table
declare #user_list table (id int)
insert #user_list(id)
SELECT user_list
FROM sometable
WHERE rowNum=xxx
SELECT *
FROM anotherTable
WHERE user_id IN(select Id from #user_list)
you can use dynamic sql
exec('
SELECT *
FROM anotherTable
WHERE user_id IN('+#user_list+')')
I want to set a variable as a string of values. E.g.
declare #FirstName char(100)
select #FirstName = 'John','Sarah','George'
SELECT *
FROM Accounts
WHERE FirstName in (#FirstName)
I'm getting a syntax error in the line select #FirstName = 'John','Sarah','George':
Incorrect syntax near ','
Is there any way I can set the variable with many values?
declare #tab table(FirstName varchar(100))
insert into #tab values('John'),('Sarah'),('George')
SELECT *
FROM #tab
WHERE 'John' in (FirstName)
You're trying to assign three separate string literals to a single string variable. A valid string variable would be 'John, Sarah, George'. If you want embedded single quotes between the double quotes, you have to escape them.
Also, your actual SELECT won't work, because SQL databases won't parse the string variable out into individual literal values. You need to use dynamic SQL instead, and then execute that dynamic SQL statement. (Search this site for dynamic SQL, with the database engine you're using as the topic (as in [sqlserver] dynamic SQL), and you should get several examples.)
-- create test table "Accounts"
create table Accounts (
c_ID int primary key
,first_name varchar(100)
,last_name varchar(100)
,city varchar(100)
);
insert into Accounts values (101, 'Sebastian', 'Volk', 'Frankfurt' );
insert into Accounts values (102, 'Beate', 'Mueller', 'Hamburg' );
insert into Accounts values (103, 'John', 'Walker', 'Washington' );
insert into Accounts values (104, 'Britney', 'Sears', 'Holywood' );
insert into Accounts values (105, 'Sarah', 'Schmidt', 'Mainz' );
insert into Accounts values (106, 'George', 'Lewis', 'New Jersey' );
insert into Accounts values (107, 'Jian-xin', 'Wang', 'Peking' );
insert into Accounts values (108, 'Katrina', 'Khan', 'Bolywood' );
-- declare table variable
declare #tb_FirstName table(name varchar(100));
insert into #tb_FirstName values ('John'), ('Sarah'), ('George');
SELECT *
FROM Accounts
WHERE first_name in (select name from #tb_FirstName);
SELECT *
FROM Accounts
WHERE first_name not in (select name from #tb_FirstName);
go
drop table Accounts;
go
A quick way to turn your varchar variable to a table (array of values) is to have your FirstName variable as a whole varchar first and then use the STRING_SPLIT method.
declare #FirstName varchar(100)
select #FirstName = 'John,Sarah,George'
SELECT *
FROM Accounts
WHERE FirstName in (SELECT * FROM STRING_SPLIT(#FirstName, ','))
In SQL you can not have a variable array.
However, the best alternative solution is to use a temporary table.
I just want to extend #Code Save's answer
--collection table is required, since we cannot use directly arrays in TSQL
declare #CollectionTable table(FirstName varchar(100))
insert into #CollectionTable values('John'),('Sarah'),('George')
SELECT * FROM TargetTable
WHERE Name IN (SELECT * FROM #CollectionTable)
In this way we can use the result from the SELECT statement from our #CollectionTable to be evaluated in the IN operator. And of course we can re-use the #CollectionTable as many times as we need.
Having a SQL table like
UserID |Attribute | Value
1 |Username | Marius
1 |Password | Fubar
I want to create an output like:
1 | Marius | Fubar
Maybe I'm just too tired to see it, doesn't sound too complicated, but I just can't seem to figure it out. Any help is appreciated.
Why don't you use self joins, ie. :
select u1.userid, u1.value, u2.value
from yourtable u1
inner join yourtable u2 on u2.userid=u1.userid
where u1.attribute='Username' and u2.attribute='Password';
Would something like...
SELECT userID,
GROUP_CONCAT (Value SEPARATOR '|')
FROM my_table
GROUP BY UserID;
be what you are looking for?
If you keep your data that way, you will need to do a crosstab query and pivot your rows into columns. If you are using Microsoft SQL Server, check out "crosstab query" and the pivot operator in Books Online.
Edited:
One column per result:
If you try to combine multiple Attributes with the same UserID it would be something like this:
Short query (one UserID):
declare #concattedtext varchar(1000)
SELECT #concattedtext=coalesce(#concattedtext + '|', '') + Value
FROM #users WHERE UserID=1
SELECT #concattedtext
RESULT with your example data:
1 | Marius | Fubar
Full query (all UserID's)
-- Your source table
CREATE Table #users (UserID int, Attribute varchar(50), Value varchar(50))
-- some entries
INSERT into #users (UserID, Attribute, Value)
VALUES (1, 'Test1', 'attr1')
INSERT into #users (UserID, Attribute, Value)
VALUES (1, 'Test2', 'attr2')
INSERT into #users (UserID, Attribute, Value)
VALUES (1, 'Test3', 'attr3')
INSERT into #users (UserID, Attribute, Value)
VALUES (2, 'Test4', 'attr4')
-- ids table variable (for distinct UserID's)
DECLARE #ids TABLE
(
rownum int IDENTITY (1, 1) Primary key NOT NULL,
UserID int
)
-- Output table variable
DECLARE #out TABLE
(
rownum int IDENTITY (1, 1) Primary key NOT NULL,
UserID int,
ConcatText varchar(1000)
)
-- get distinct id's
INSERT INTO #ids(UserID)
SELECT DISTINCT(UserID) FROM #users
-- Foreach vars
declare #RowCnt int
declare #MaxRows int
select #RowCnt = 1
select #MaxRows=count(*) from #ids
-- UserID
declare #id int
declare #concattedtext varchar(1000)
-- process each id
while #RowCnt <= #MaxRows
begin
SET #id = 0
SELECT #id=UserID
FROM #ids WHERE rownum=#RowCnt
SET #concattedtext = CONVERT(nvarchar(50), #id)
FROM #ids WHERE rownum=#RowCnt
SELECT #concattedtext=coalesce(#concattedtext + '|', '') + Value
FROM #users WHERE UserID=#id
INSERT INTO #out(UserID, ConcatText)
VALUES (#id, #concattedtext)
-- next UserID
Select #RowCnt = #RowCnt + 1
end
SELECT * FROM #out
DROP TABLE #users
Result:
rownum|UserID|ConcatTex
1 | 1 |1|attr1|attr2|attr3
2 | 2 |2|attr4
DROP TABLE #users
You might need a sort field to get your parameters in your requested order.
Multiple columns
Your data needs to have an equal count of attributes if you like to get a table with multiple columns. And you still need to take care about the ordering.
In this case a hardcoded query with a group by would be your choice.