【问题标题】:Update a Table by Passing Table Name, ColumnName as a Variable Using Cursor通过使用游标将表名、列名作为变量传递来更新表
【发布时间】:2011-09-21 07:22:41
【问题描述】:

我想更新一个表。我从前端获取表名和列名作为 XML 数据集。我为此写了一个光标。但它会引发错误。下面是我的光标

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[PMT_Formstatus_Update_Test]
(
@XMLTableNames VARCHAR(MAX)
)
AS
BEGIN

DECLARE @docHandle INT, @ErrorMessage VARCHAR(200), @doc VARCHAR(200)
    SET @doc = '<?xml version="1.0" encoding="iso-8859-1" ?>'

    DECLARE @Names TABLE
(   
        TName VARCHAR(50),
    CName VARCHAR(50),
    IDField VARCHAR(50),
    FunctionID INT,
    ID INT,             
    StatusID INT
    )
    SET @XMLTableNames = @doc + @XMLTableNames          
EXEC sp_xml_preparedocument @docHandle OUTPUT,  @XMLTableNames
    INSERT INTO @Names
    SELECT * FROM 
        OPENXML(@docHandle,'NewDataSet/NameDetails',2)
            WITH
            (
                TName VARCHAR(50),
                CName VARCHAR(50),
                IDField VARCHAR(50),
                FunctionID INT,
                ID INT,
                StatusID INT
                            )

    DECLARE @FunctionID INT
DECLARE @StatusID INT
DECLARE @ID INT
    DECLARE @TableName VARCHAR(50)
    DECLARE @ColumnName VARCHAR(50)
DECLARE @IDField VARCHAR(50)

    DECLARE @getTables CURSOR
    SET @getTables = CURSOR FOR
    SELECT FunctionID, TName, CName, StatusID, IDField, ID FROM @Names
    OPEN @getTables
    FETCH NEXT
    FROM @getTables INTO @FunctionID, @TableName, @ColumnName, @StatusID, @IDField, @ID
    WHILE @@FETCH_STATUS = 0
    BEGIN
    UPDATE @TableName SET @ColumnName = 3 WHERE @IDField = @ID
        FETCH NEXT
    FROM @getTables INTO @FunctionID, @TableName, @ColumnName, @StatusID, @IDField, @ID
    END

    CLOSE @getTables
    DEALLOCATE @getTables
END

在这种情况下如何编写更新查询?请我需要你的所有建议...

【问题讨论】:

  • 您为什么需要/想要这样做?
  • 实际上,我从前端获取所有上述变量作为 xml 数据集。根据我要更新对应表的值。

标签: sql sql-server-2008 sql-server-2005 variables sql-update


【解决方案1】:

您需要将它们连接为字符串,然后调用EXEC('')

EXEC ('UPDATE TableName SET ColumnName1 = 3 WHERE ColumnName2= Value')

【讨论】:

    【解决方案2】:

    简单的动态 SQL 示例:

    DECLARE @SQL NVARCHAR(max),@TableName VARCHAR(128),@ColumnName1 VARCHAR(128),@ColumnName2 VARCHAR(128),@Value NVARCHAR(MAX),@NewValue NVARCHAR(MAX)
    SET @TableName='User'
    SET @ColumnName1='Session_Id'
    SET @ColumnName2='Session_Id_Old'
    SET @Value=''''+CAST(NEWID() as NVARCHAR(50))+''''
    SET @NewValue=''''+CAST(NEWID() as NVARCHAR(50))+''''
    
    SET @SQL=
    REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
    'UPDATE [@TableName] SET [@ColumnName1] = @NewValue WHERE [@ColumnName2]= @Value','@TableName',@TableName),
    '@ColumnName1',@ColumnName1),'@Value',@Value),'@NewValue',@NewValue),'@ColumnName2',@ColumnName2)
            EXECUTE(@SQL)
    

    如果数据类型是字符串,则应在旧值/新值的两侧添加撇号

    【讨论】:

      【解决方案3】:

      您可以希望看到为什么您编写的内容不起作用,因为它是针对表变量执行的更新语句,不会影响该表中的实际列:

      declare @TableName table (ID int not null)
      declare @ColumnName1 int
      declare @ColumnName2 int
      declare @Value int
      UPDATE @TableName SET @ColumnName1 = 3 WHERE @ColumnName2= @Value
      

      尝试实现您正在做的事情的一种方法是动态 SQL。它很难看(如果列中的数据类型不同,情况会更糟)。 T-SQL 中没有内置真正的“元编程”系统。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-08
        • 1970-01-01
        • 2015-11-21
        • 1970-01-01
        • 2016-10-24
        • 1970-01-01
        相关资源
        最近更新 更多