Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.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
Sql server 如何将一组静态数据和列数据列表同时传递到存储过程中?_Sql Server_Stored Procedures - Fatal编程技术网

Sql server 如何将一组静态数据和列数据列表同时传递到存储过程中?

Sql server 如何将一组静态数据和列数据列表同时传递到存储过程中?,sql-server,stored-procedures,Sql Server,Stored Procedures,我的存储过程是 ALTER PROCEDURE [dbo].[Register] @Id int, @Name nvarchar(50) AS BEGIN BEGIN TRY INSERT INTO dbo.Group (Id, Name) VALUES(@Id, @Name) SELECT 0 END TRY BEGIN CATCH SELECT -1 END

我的存储过程是

   ALTER PROCEDURE [dbo].[Register]
    @Id        int,
    @Name nvarchar(50)
AS
BEGIN
    BEGIN TRY
        INSERT INTO dbo.Group (Id, Name) 
        VALUES(@Id, @Name)

        SELECT 0
    END TRY
    BEGIN CATCH
        SELECT -1
    END CATCH
END
GO
我想像这样传递数据,以便插入到这个表中

@Id = 1 
@Name = 'test1,test2,test3,test4,test5'
结果是这样的

Id   Name
1    test1
1    test2
1    test3
1    test4
1    test5

请分享实现此目标的最佳方法。

SQL Server 2016提供了
string\u split()
,它正是您想要做的:

ALTER PROCEDURE [dbo].[Register] (
    @Id   int,
    @Name nvarchar(max)
) AS
BEGIN
    BEGIN TRY
        WITH s AS (
            SELECT STRING
        INSERT INTO dbo.Group (Id, Name) 
            VALUES(@Id, @Name)
            SELECT i.id, s.val
            FROM (SELECT @id as id) s CROSS APPLY
                 STRING_SPLIT(name, ',') s(val)

        SELECT 0
    END TRY
    BEGIN CATCH
        SELECT -1
    END CATCH
END;
GO

对于早期版本的SQL Server,您可以在web上找到
string\u split()
的代码。

SQL Server 2016提供了
string\u split()
,这正是您想要做的:

ALTER PROCEDURE [dbo].[Register] (
    @Id   int,
    @Name nvarchar(max)
) AS
BEGIN
    BEGIN TRY
        WITH s AS (
            SELECT STRING
        INSERT INTO dbo.Group (Id, Name) 
            VALUES(@Id, @Name)
            SELECT i.id, s.val
            FROM (SELECT @id as id) s CROSS APPLY
                 STRING_SPLIT(name, ',') s(val)

        SELECT 0
    END TRY
    BEGIN CATCH
        SELECT -1
    END CATCH
END;
GO

对于早期版本的SQL Server,您可以在web上找到
string\u split()
的代码。

首先创建一个拆分函数,如下所示:

create FUNCTION [dbo].[fnSplit](
    @sInputList VARCHAR(max) -- List of delimited items
  , @sDelimiter VARCHAR(5) -- delimiter that separates items
) RETURNS @List TABLE (item VARCHAR(max))

BEGIN
DECLARE @sItem VARCHAR(max)
WHILE CHARINDEX(@sDelimiter,@sInputList,0) <> 0
 BEGIN
 SELECT
  @sItem=RTRIM(LTRIM(SUBSTRING(@sInputList,1,CHARINDEX(@sDelimiter,@sInputList,0)-1))),
  @sInputList=RTRIM(LTRIM(SUBSTRING(@sInputList,CHARINDEX(@sDelimiter,@sInputList,0)+LEN(@sDelimiter),LEN(@sInputList))))

 IF LEN(@sItem) > 0
  INSERT INTO @List SELECT @sItem
 END

IF LEN(@sInputList) > 0
 INSERT INTO @List SELECT @sInputList -- Put the last item in
RETURN
END
这是回报

1   test1
1   test2
1   test3
1   test4
1   test5

显然,您将不需要选择,但我只是想表明插入工作

首先创建一个拆分函数,如下所示:

create FUNCTION [dbo].[fnSplit](
    @sInputList VARCHAR(max) -- List of delimited items
  , @sDelimiter VARCHAR(5) -- delimiter that separates items
) RETURNS @List TABLE (item VARCHAR(max))

BEGIN
DECLARE @sItem VARCHAR(max)
WHILE CHARINDEX(@sDelimiter,@sInputList,0) <> 0
 BEGIN
 SELECT
  @sItem=RTRIM(LTRIM(SUBSTRING(@sInputList,1,CHARINDEX(@sDelimiter,@sInputList,0)-1))),
  @sInputList=RTRIM(LTRIM(SUBSTRING(@sInputList,CHARINDEX(@sDelimiter,@sInputList,0)+LEN(@sDelimiter),LEN(@sInputList))))

 IF LEN(@sItem) > 0
  INSERT INTO @List SELECT @sItem
 END

IF LEN(@sInputList) > 0
 INSERT INTO @List SELECT @sInputList -- Put the last item in
RETURN
END
这是回报

1   test1
1   test2
1   test3
1   test4
1   test5

显然,您将不需要选择,但我只是想表明插入工作

您可以使用TVPs:

  • 创建用户定义的表类型

    CREATE TYPE [dbo].[TestTableType] AS TABLE(
                                                Id [int] NOT NULL,
                                                Name varchar(10)
                                              )
    
  • 将其作为参数传递给存储过程

    ALTER PROCEDURE [dbo].[Register]
        @testTable TestTableType READONLY
    AS
    BEGIN
    BEGIN TRY
        INSERT INTO dbo.Group (Id, Name) 
        SELECT *
        FROM @testTable
    
        SELECT 0
    END TRY
    BEGIN CATCH
        SELECT -1
    END CATCH
    END
    

  • 您可以在中找到更多信息,请注意,当TVP用作存储过程的参数时,必须声明为
    只读

    您可以使用TVP:

  • 创建用户定义的表类型

    CREATE TYPE [dbo].[TestTableType] AS TABLE(
                                                Id [int] NOT NULL,
                                                Name varchar(10)
                                              )
    
  • 将其作为参数传递给存储过程

    ALTER PROCEDURE [dbo].[Register]
        @testTable TestTableType READONLY
    AS
    BEGIN
    BEGIN TRY
        INSERT INTO dbo.Group (Id, Name) 
        SELECT *
        FROM @testTable
    
        SELECT 0
    END TRY
    BEGIN CATCH
        SELECT -1
    END CATCH
    END
    

  • 您可以在中找到更多信息,请注意TVP,当用作存储过程的参数时,必须声明为
    只读

    。在这种情况下,您可以使用用户指定的表格数据类型并将表传递给存储过程,也可以使用逗号将字符串从单个varchar参数中拆分。在这种情况下,您可以使用用户指定的表格数据类型并传递表到存储过程,或者可以使用逗号从单个varchar参数拆分字符串。请不要使用此拆分器。这是可怕的表现。它是一个包含循环的多语句表值函数。这里有几个更好的拆分器。请不要使用此拆分器。这是可怕的表现。它是一个包含循环的多语句表值函数。这里有几个更好的拆分器。