存储过程中 IN 运算符导致数据类型 nvarchar 转换为 bigint 时出错
Error converting data type nvarchar to bigint caused by IN operator in Stored Procedure
存储过程:
ALTER PROCEDURE [dbo].[MyProcedure]
@CommaSeperatedValues nvarchar(500)
AS
BEGIN
SET NOCOUNT ON;
SELECT Col1, Col2, Col3
FROM MyTable
WHERE SomeCol_BigIntDataType IN (@CommaSeperatedValues)
来自代码的值是字符串值:“9010073,9010074”
我试过 运行 SP 是这样的:exec MyProcedure '9010073,9010074'
这给出了错误 'Error converting data type nvarchar to bigint' 而 运行 宁 SP
如果我运行把select分开查询,像这样:
SELECT Col1, Col2, Col3
FROM MyTable
WHERE SomeCol_BigIntDataType IN (9010073,9010074)
然后我得到了预期的结果。
但我想 运行 来自 SP。
您需要一个函数来将逗号分隔的字符串拆分成单独的行。然后你像这样调用函数:
SELECT
Col1, Col2, Col3
FROM MyTable
WHERE
SomeCol_BigIntDataType IN (
SELECT CAST(Item AS BIGINT)
FROM dbo.[DelimitedSplitN4K](@CommaSeperatedValues, ',')
)
这是 Jeff Moden 的 DelimitedSplitN4K
函数。更多信息:http://www.sqlservercentral.com/articles/Tally+Table/72993/
CREATE FUNCTION [dbo].[DelimitedSplitN4K](
@pString NVARCHAR(4000), @pDelimiter NCHAR(1)
)
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
WITH E1(N) AS (
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
)
,E2(N) AS (SELECT 1 FROM E1 a, E1 b)
,E4(N) AS (SELECT 1 FROM E2 a, E2 b)
,cteTally(N) AS(
SELECT TOP (ISNULL(DATALENGTH(@pString)/2,0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)
,cteStart(N1) AS(
SELECT 1 UNION ALL
SELECT t.N+1 FROM cteTally t WHERE SUBSTRING(@pString,t.N,1) = @pDelimiter
),
cteLen(N1,L1) AS(
SELECT
s.N1,
ISNULL(NULLIF(CHARINDEX(@pDelimiter,@pString,s.N1),0)-s.N1,4000)
FROM cteStart s
)
SELECT
ItemNumber = ROW_NUMBER() OVER(ORDER BY l.N1),
Item = SUBSTRING(@pString, l.N1, l.L1)
FROM cteLen l
;
GO
免责声明:注释已从函数中删除,格式已修改。
在数据库中创建以下表格函数作为 SplitString。当你想要select项时;使用这个:
Select Part from SplitString(@YourValues, ',')
您的查询中使用了以上 select 语句。
SELECT Col1, Col2, Col3
FROM MyTable
WHERE SomeCol_BigIntDataType IN (Select Part from SplitString(@CommaSeperatedValues, ','))
以下函数在您的数据库中执行一次。
CREATE FUNCTION [dbo].[SplitString]
(
-- Add the parameters for the function here
@myString varchar(500),
@deliminator varchar(10)
)
RETURNS
@ReturnTable TABLE
(
-- Add the column definitions for the TABLE variable here
[id] [int] IDENTITY(1,1) NOT NULL,
[part] [varchar](50) NULL
)
AS
BEGIN
Declare @iSpaces int
Declare @part varchar(50)
--initialize spaces
Select @iSpaces = charindex(@deliminator,@myString,0)
While @iSpaces > 0
Begin
Select @part =
substring(@myString,0,charindex(@deliminator,@myString,0))
Insert Into @ReturnTable(part)
Select @part
Select @myString =
substring(@mystring,charindex(@deliminator,@myString,0)+
len(@deliminator),len(@myString) - charindex(' ',@myString,0))
Select @iSpaces = charindex(@deliminator,@myString,0)
end
If len(@myString) > 0
Insert Into @ReturnTable
Select @myString
RETURN
END
我们开始吧。你可以通过动态查询
DECLARE @mystring NVARCHAR(max)
DECLARE @UserId NVARCHAR(max)
SET @UserId = '9010073,9010074'
SELECT @mystring = 'SELECT Col1, Col2, Col3 FROM MyTable where UserId IN('+ @UserId +')'
EXEC sp_executesql @mystring
存储过程:
ALTER PROCEDURE [dbo].[MyProcedure]
@CommaSeperatedValues nvarchar(500)
AS
BEGIN
SET NOCOUNT ON;
SELECT Col1, Col2, Col3
FROM MyTable
WHERE SomeCol_BigIntDataType IN (@CommaSeperatedValues)
来自代码的值是字符串值:“9010073,9010074”
我试过 运行 SP 是这样的:exec MyProcedure '9010073,9010074'
这给出了错误 'Error converting data type nvarchar to bigint' 而 运行 宁 SP
如果我运行把select分开查询,像这样:
SELECT Col1, Col2, Col3
FROM MyTable
WHERE SomeCol_BigIntDataType IN (9010073,9010074)
然后我得到了预期的结果。
但我想 运行 来自 SP。
您需要一个函数来将逗号分隔的字符串拆分成单独的行。然后你像这样调用函数:
SELECT
Col1, Col2, Col3
FROM MyTable
WHERE
SomeCol_BigIntDataType IN (
SELECT CAST(Item AS BIGINT)
FROM dbo.[DelimitedSplitN4K](@CommaSeperatedValues, ',')
)
这是 Jeff Moden 的 DelimitedSplitN4K
函数。更多信息:http://www.sqlservercentral.com/articles/Tally+Table/72993/
CREATE FUNCTION [dbo].[DelimitedSplitN4K](
@pString NVARCHAR(4000), @pDelimiter NCHAR(1)
)
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
WITH E1(N) AS (
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
)
,E2(N) AS (SELECT 1 FROM E1 a, E1 b)
,E4(N) AS (SELECT 1 FROM E2 a, E2 b)
,cteTally(N) AS(
SELECT TOP (ISNULL(DATALENGTH(@pString)/2,0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)
,cteStart(N1) AS(
SELECT 1 UNION ALL
SELECT t.N+1 FROM cteTally t WHERE SUBSTRING(@pString,t.N,1) = @pDelimiter
),
cteLen(N1,L1) AS(
SELECT
s.N1,
ISNULL(NULLIF(CHARINDEX(@pDelimiter,@pString,s.N1),0)-s.N1,4000)
FROM cteStart s
)
SELECT
ItemNumber = ROW_NUMBER() OVER(ORDER BY l.N1),
Item = SUBSTRING(@pString, l.N1, l.L1)
FROM cteLen l
;
GO
免责声明:注释已从函数中删除,格式已修改。
在数据库中创建以下表格函数作为 SplitString。当你想要select项时;使用这个:
Select Part from SplitString(@YourValues, ',')
您的查询中使用了以上 select 语句。
SELECT Col1, Col2, Col3
FROM MyTable
WHERE SomeCol_BigIntDataType IN (Select Part from SplitString(@CommaSeperatedValues, ','))
以下函数在您的数据库中执行一次。
CREATE FUNCTION [dbo].[SplitString]
(
-- Add the parameters for the function here
@myString varchar(500),
@deliminator varchar(10)
)
RETURNS
@ReturnTable TABLE
(
-- Add the column definitions for the TABLE variable here
[id] [int] IDENTITY(1,1) NOT NULL,
[part] [varchar](50) NULL
)
AS
BEGIN
Declare @iSpaces int
Declare @part varchar(50)
--initialize spaces
Select @iSpaces = charindex(@deliminator,@myString,0)
While @iSpaces > 0
Begin
Select @part =
substring(@myString,0,charindex(@deliminator,@myString,0))
Insert Into @ReturnTable(part)
Select @part
Select @myString =
substring(@mystring,charindex(@deliminator,@myString,0)+
len(@deliminator),len(@myString) - charindex(' ',@myString,0))
Select @iSpaces = charindex(@deliminator,@myString,0)
end
If len(@myString) > 0
Insert Into @ReturnTable
Select @myString
RETURN
END
我们开始吧。你可以通过动态查询
DECLARE @mystring NVARCHAR(max)
DECLARE @UserId NVARCHAR(max)
SET @UserId = '9010073,9010074'
SELECT @mystring = 'SELECT Col1, Col2, Col3 FROM MyTable where UserId IN('+ @UserId +')'
EXEC sp_executesql @mystring