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参数拆分字符串。请不要使用此拆分器。这是可怕的表现。它是一个包含循环的多语句表值函数。这里有几个更好的拆分器。请不要使用此拆分器。这是可怕的表现。它是一个包含循环的多语句表值函数。这里有几个更好的拆分器。