Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SQL:如何执行返回列为“IN”参数的值的存储过程?_C#_Sql_Sql Server_Stored Procedures - Fatal编程技术网

C# SQL:如何执行返回列为“IN”参数的值的存储过程?

C# SQL:如何执行返回列为“IN”参数的值的存储过程?,c#,sql,sql-server,stored-procedures,C#,Sql,Sql Server,Stored Procedures,我有一个表,当特定的列值在parameter not=parameter中时,我需要存储过程返回所有行 USE [MyDatabase] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[TestGetDataInParameter] @MyParameter nvarchar(MAX) AS BEGIN SELECT * FROM MyTable WHE

我有一个表,当特定的列值在parameter not=parameter中时,我需要存储过程返回所有行

USE [MyDatabase]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[TestGetDataInParameter] 
    @MyParameter nvarchar(MAX)
AS
BEGIN
    SELECT *  
    FROM MyTable
    WHERE MyColum IN (@MyParameter)
END

我有执行此存储过程的C代码,我不知道应该以何种格式传递参数才能正确执行查询。

一如既往,答案是,这取决于具体情况。所以,首先。。。当前显示的语法

WHERE MyColum IN (@MyParameter)
如果尝试传递多个值,则将失败。如果不想从应用程序中传递逗号分隔的列表或数组,则首先需要将字符串解析为单独的值。如果您使用的是SQL Server 2016或Azure,那么这项任务就轻而易举了。只需使用STRING_SPLIT函数。如果你没有,你会想找到一个好的字符串拆分器。我最喜欢的是,或者如果你对CRL组件感到满意的话,有一个据说比周围任何东西都快的CRL组件

所以,问题1解决了。。。问题2,如果某个特定值包含在值字符串中,您希望基本上完全忽略筛选器

同样,一旦字符串被拆分,查找值就变得非常容易了。您可以使用或@SomeParameter=MagicValue禁用过滤器

下面应该说明这个想法

DECLARE @ValuesList VARCHAR(1000) = '-1,1048309,1308584,1491312,1959807,2024608,2428302,2552655,2617456,2623776';

IF OBJECT_ID('tempdb..#ParameterValues', 'U') IS NOT NULL 
DROP TABLE #ParameterValues;

SELECT Item = CAST(sc.Item AS INT) INTO #ParameterValues FROM dbo.SplitCSVToTable8K(@ValuesList, ',') sc;

DECLARE @GetAll BIT = 0;  -- ( -1 is the "all" value from the input string )
SELECT @GetAll = 1 FROM #ParameterValues pv WHERE pv.Item = 1;

SELECT 
    *
FROM
    sys.sysobjects o
    LEFT JOIN #ParameterValues pv
        ON o.id = pv.Item
WHERE 
    (
        pv.Item IS NOT NULL
        OR 
        @GetAll = 1
    )
OPTION(RECOMPILE);

请注意在查询中使用了OPTIONRECOMPILE。使用这样的可选参数将导致优化器忽略任何SEEK执行计划选项。OPTIONRECOMPILE允许优化器在创建计划之前等待并查看传递给参数的值(如果有),从而允许搜索操作。

创建以下函数。。接受字符串的简单函数。。随着分离器,吐出一张桌子

CREATE FUNCTION [dbo].[F_SplitList](@String nvarchar(4000), @Delimiter char(1))
RETURNS @Results TABLE (value nvarchar(4000))
AS

    BEGIN
    DECLARE @INDEX INT
    DECLARE @SLICE nvarchar(4000)
    -- HAVE TO SET TO 1 SO IT DOESNT EQUAL Z
    --     ERO FIRST TIME IN LOOP
    SELECT @INDEX = 1

    IF @String IS NULL RETURN
    WHILE @INDEX !=0


        BEGIN    
            -- GET THE INDEX OF THE FIRST OCCURENCE OF THE SPLIT CHARACTER
            SELECT @INDEX = CHARINDEX(@Delimiter,@STRING)
            -- NOW PUSH EVERYTHING TO THE LEFT OF IT INTO THE SLICE VARIABLE
            IF @INDEX !=0
                SELECT @SLICE = LEFT(@STRING,@INDEX - 1)
            ELSE
                SELECT @SLICE = @STRING
            -- PUT THE ITEM INTO THE RESULTS SET
            INSERT INTO @Results(value) VALUES(@SLICE)
            -- CHOP THE ITEM REMOVED OFF THE MAIN STRING
            SELECT @STRING = RIGHT(@STRING,LEN(@STRING) - @INDEX)
            -- BREAK OUT IF WE ARE DONE
            IF LEN(@STRING) = 0 BREAK
    END

    RETURN
END
然后你可以这样叫你的Where:

WHERE MyColum in (Select * from(dbo.F_SplitList(@MyParameter,',')) 

像这样传递MyParameter值:“var1,var2,var3”

是的,在这种情况下,您必须使用split函数,并按照这里的说明进行操作

另一种方式,

declare @MyParameter varchar(50)='1,2,3'
declare @Sql nvarchar(max)=''


set @Sql=
N'SELECT *  FROM HumanResources.Employee
WHERE BusinessEntityID IN ('+@MyParameter+')'
exec sp_executesql @Sql, N'@MyParameter1 varchar(50)', @MyParameter1 = @MyParameter
试试这个:

USE [MyDatabase]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
alter PROCEDURE [dbo].[TestGetDataInParameter] @MyParameter nvarchar(MAX)
AS
BEGIN
declare @str nvarchar(MAX)
set @str = 'SELECT *  FROM MyTable
WHERE MyColum IN ('+@MyParameter+')'
exec(@str)
print @str
END

exec [TestGetDataInParameter] "'abc','xyz'"

看起来MyColumn是varchar,所以您应该从CYeah以字符串的形式传递参数,我的意思是字符串应该像val1,val2,。。或者'val1','val2',我在询问应该发送到过程的输入格式。应该是-'val1','val2'。删除引号中的多余空格。如果没有动态SQL,这将不起作用,因为无论您如何格式化字符串,SQL都会将其解释为字符串。。。实际上,您应该传递一个datatable,并使存储过程的参数为TVP,但如果失败,则需要一个字符串拆分器。不管你做什么,你都需要重建存储过程的编写方式。@ZLK是的,我尝试过的所有格式都不起作用,你能帮我修改存储过程吗?这将是伟大的,如果你能提供一个例子或链接,显示如何做到这一点的例子。