I have a query like this when I pass the values into in operator in sql it shows:
Conversion failed when converting the varchar value '3,4,9' to data type int.
How can I solve the issue?
declare #values varchar(100)
set #values = '3,4,9'
select #values
select * from CmnItemType where ItemTypeID in (#values)
No. You can use string_split() or a similar user-defined function:
where itemtypeid in (select try_convert(int, value) from string_split(#values))
What I usually do is use table variable, like this one:
DECLARE #values TABLE (id INT)
INSERT INTO #values (id) VALUES (3),(4),(9)
SELECT id FROM #values
From that, you could simply do a join to your tables.
If you are creating a stored procedure, you can use a TVP to pass parameters, here is the Microsoft doc on that. With a TVP, your code can simply call your SP with a list and you will be able to join it in the SP.
Hope this will help.
Related
I am writing a SQL Query based of user input, as these inputs will change on a daily basis.
The goal of the query is to pull all data for only the ID's in the user-defined list. Example below-
However, I am getting the following error:
"Conversion failed when converting the varchar [...] to data type int"
Any idea on what the optimal way to specify a list and use that list at the "ID in (..)" clause?
I have tried converting the ID list into strings, but still receiving a similar error.
id_list = [12,16,22,42,1,24]
date = '2020-12-18'
query = (
"""
DECLARE #id varchar(1000), #date datetime
SET #id = '{}'
SET #date = '{}'
SELECT * from TABLE where ID in (#id) and Date = #Date
"""
.format(id_list,date))
The desired result is for a query to be able to take a list of IDs that could be utilized in the clause.
id in #id
SQL Server doesn't support lists or arrays. So the best method is a table:
declare #id_list table (id int);
insert into #idlist (id)
values (12), (16), (22), (42), (1), (24);
You can then use this wherever you would use a table variable. For instance:
where id in (select id from #id_list)
I want to store values from a SELECT statement into a variable which is capable of holding more than one value because my SELECT statement returns multiple values of type INT. This is how my SP looks like so far.
ALTER PROCEDURE "ESG"."SP_ADD"
AS
BEGIN
DECLARE #Id table(identifiers VARCHAR);
INSERT INTO #Id (identifiers) VALUES('axaa1aaa-aaaa-a5aa-aaaa-aa8aaaa9aaaa');
INSERT INTO #Id (identifiers) VALUES('bxbb1bbb-bbbb-b5bb-bbb4-bb8bbbb9bbbf');
DECLARE #tranID INT = (SELECT
DOCUMENT_SET_.DOCUMENT_SET_TRANSACTION_ID
FROM DOCUMENT_SET_TRANSACTION
WHERE DOCUMENT_SET_TRANSACTION.IDENTIFIER IN (SELECT identifiers FROM #Id));
END
Variable #tranID should be a list or an array to hold the ids. Is it possible to do it SQL Server?
You can declare a variable of type table
DECLARE #tblTrans TABLE (
tranID INT
);
INSERT INTO #tblTrans
SELECT DOCUMENT_SET_TRANSACTION.DOCUMENT_SET_TRANSACTION_ID
FROM ESG.DOCUMENT_SET_TRANSACTION
WHERE DOCUMENT_SET_TRANSACTION.IDENTIFIER
IN (SELECT identifiers FROM #envelopeId);
Depending on what you want to do with the values after this, you could declare a cursor to loop through them or select straight from the variable.
You could also look into using a temporary table depending on what scope you need.
Try this, only take the firs row of example. Do u try this?
select DOCUMENT_SET_TRANSACTION.DOCUMENT_SET_TRANSACTION_ID,
(STUFF((SELECT '-' + convert(varchar(max),DOCUMENT_SET_TRANSACTION.DOCUMENT_SET_TRANSACTION_ID)
FROM ESG.DOCUMENT_SET_TRANSACTION
FOR XML PATH ('')), 1, 2, '')) AS example
FROM ESG.DOCUMENT_SET_TRANSACTION
Here is the deal, I am receiving an array from C# and I want to insert it into the following table with only 2 columns which are #idUser int and #idRegion int.
The stored procedure needs to receive the array and insert it into the table but somehow it isn't working, it tells me that it cannot convert #idRegion to an int. I tried to use CAST and CONVERT to convert it into int but it isn't working.
The Select From works ok, but not the insert.
Here is the stored procedure (#idUser needs to be the same for all inserted rows):
#idUser int,
#idRegion nvarchar(MAX)
AS
BEGIN
INSERT INTO [UsersRegion] (idUser,IdRegion)
VALUES (#idUser, #idRegion)
SELECT #idUser,cast(value as int) FROM STRING_SPLIT(#idRegion,',')
END
I get this error when running it:
Conversion failed when converting the nvarchar value '1,2,3,4' to data type int.
If you are sending multiple values in #idRegion then when you split them, you may have more than 1 things you need to insert. Therefore, do it like this:
INSERT INTO [UsersRegion] (idUser,IdRegion)
SELECT #idUser, value FROM STRING_SPLIT(#idRegion, ',')
If the target table's IdRegion column is of type int, you need to cast like this:
SELECT #idUser, cast(value as int) FROM STRING_SPLIT(#idRegion, ',')
Above code will insert the same #idUser for every record but a different value for IdRegion depending the splitted items. More on Insert into select from
Your INSERT statement seems to be working with IdRegion while everything else is lowercase id.
However, assuming this is how the actual table column is named and is not a typo...
Your problem is most likely the line that reads:
#idRegion nvarchar(MAX)
Which is declaring the #idRegion variable as a string, while you have stated in the question that it's meant to be an int.
This would explain the casting error.
If you cannot pass it into the procedure as an int from the C# code. Your only other option would be to try to parse it into an int as you have said.
Is there a way to input multiple values in a single parameter of a scalar-valued function in SQL Server 2008 R2 and have it filter data by that parameter using both values?
For example I would like to do the following
SET #Salesperson='BILL' OR 'MOSES'
SELECT Sum(SalesDollars)
FROM Invoices
WHERE Invoices.Salesperson = #Salesperson
I attempted to use the following as the WHERE clause, but this didnt work either.
SET #Salesperson='BILL','MOSES'
SELECT Sum(SalesDollars)
FROM Invoices
WHERE Invoices.Salesperson IN (#Salesperson)
Would it be easier if i were dealing with integers as opposed to varchar values?
Any help would be absolutely appreciated!
You need to use table-valued parameters. Look it up on technet or msdn
Best part of it that your table-valued parameters can have multiple columns.
Note however that you have to define TVP parameter as readonly. So if you want to return similar set from your function you will need to create another variable inside your function.
Example:
CREATE TYPE Names AS TABLE
( Name VARCHAR(50));
GO
/* Create a procedure to receive data for the table-valued parameter. */
CREATE PROCEDURE dbo.mySP
#n Names READONLY
AS
SELECT Sum(SalesDollars)
FROM
WHERE Invoices.Salesperson in (select Name from #n)
GO
CREATE FUNCTION dbo.myFun(#n Names READONLY) returns int
AS
SELECT Sum(SalesDollars)
FROM
WHERE Invoices.Salesperson in (select Name from #n)
GO
/* Declare a variable that references the type. */
DECLARE #names AS Names;
/* Add data to the table variable. */
INSERT INTO #names (Name)
VALUES ('BILL'),('MOSES')
-- using stored procedure with TVP
EXEC dbo.mySP #names
-- using function with TVP
select dbo.myFun(#names)
GO
This could be done this way:
SET #Salesperson='BILL,MOSES'
SELECT *
FROM YourTable
WHERE Invoices.Salesperson IN (SELECT * FROM dbo.split(#Salesperson,','))
This is how you split the values.
I would typically do this using a user defined table type: SQL Fiddle Example.
CREATE TYPE <schema>.SalespersonList AS TABLE
(
Name varchar(32)
)
You may have to grant execute permissions on the type:
GRANT EXECUTE ON TYPE::<schema>.SalespersonList TO <user>
Then you can create a function to use it:
CREATE FUNCTION <schema>.fnGetTotalSales
(
#nameList <schema>.SalespersonList READONLY
)
RETURNS INT
AS
BEGIN
DECLARE #ret INT
SELECT #ret = Sum(SalesDollars)
FROM Invoices i
INNER JOIN #nameList nl ON nl.Name = i.Salesperson
RETURN #ret
END
Then you would just insert your list into the type and call the function:
DECLARE #salesPersonList <schema>.SalespersonList
INSERT INTO #salesPersonList (Name)
SELECT 'Bill'
UNION
SELECT 'Moses'
SELECT <schema>.fnGetTotalSales(#salesPersonList)
What's wrong with this T-SQL :
DECLARE #temp TABLE(ID INT IDENTITY,[Value] VARCHAR(100))
SET #temp = dbo.[fnCSVToTable](',2,3')
I don't think you can assign to the table variable like that (unless it is a new thing in SQL 2008).
At least for SQL2005 you would need to do the following.
DECLARE #temp TABLE(ID INT IDENTITY,[Value] VARCHAR(100))
INSERT INTO #temp
SElECT [value]
FROM dbo.[fnCSVToTable](',2,3')
From the docs for SET (SQL 2008; SQL 2005) (my emphasis):
# local_variable
Is the name of a
variable of any type except cursor, text, ntext, image, or table.
To populate a table variable, use
INSERT #table_variable
SELECT columns
FROM dbo.fnTableValuedFunction