SQL SERVER通过表值参数

时间:2018-07-30 12:04:02

标签: sql sql-server

我有一个存储过程,将“表值参数”作为输入。它有大约15-20列。           我想在没有MERGE的情况下执行插入/更新操作,因为MERGE在table上有锁。通过做研究,我知道,游标也可以使用。但是游标会降低性能。           我发现了这篇文章(https://www.dotnettricks.com/learn/sqlserver/sql-server-cursor-alternatives),在里面的while循环中,我们获取了每个列变量,对于列数大于10的表,这将是乏味的。那么,还有其他选择吗?

2 个答案:

答案 0 :(得分:2)

您可以创建一个存储过程,并像下面的代码一样传递您的参数:

CREATE PROCEDURE [dbo].[MyStoredProcedure]
    @TableValue [dbo].[TABLETYPE] READONLY
AS
BEGIN
    UPDATE [dbo].[MyTable]
    SET Name = T.Name
    FROM [dbo].[MyTable]
        INNER JOIN @TableValue AS T ON T.Id = [dbo].[MyTable].Id
    WHERE T.Name <> [dbo].[MyTable].Name

    INSERT INTO [dbo].[MyTable](Id,Name)
    SELECT Id , Name
    FROM @TableValue AS T
    WHERE NOT EXISTS(SELECT *
                     FROM [dbo].[MyTable] 
                     WHERE Id = T.Id)
END
GO

首先更新现有记录,然后插入新行。

答案 1 :(得分:-2)

我为您创建了一个示例。这很容易。 您可以将其放入存储过程中:

DECLARE @TABLE_NAME VARCHAR(100)
DECLARE @TABLE_NAME_DEST VARCHAR(100)
DECLARE @List VARCHAR(8000)
DECLARE @SQL VARCHAR(4000)

SET @TABLE_NAME = 'Employee'
SET @TABLE_NAME_DEST = 'Employee_DEST'

SELECT @List = COALESCE(@List + ', ', '') + Column_Name 
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TABLE_NAME
-- Prevent Injection
IF (EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TABLE_NAME )) 
BEGIN
SET @SQL = 'INSERT INTO [' + @TABLE_NAME_DEST +'] (' + @List +')' +char(10)
SET @SQL = @SQL + 'SELECT ' + @List + char(10) + 'FROM ' + @TABLE_NAME

print @SQL
END

类似于SQL更新。