【问题标题】:How to update table with dynamic table name?如何使用动态表名更新表?
【发布时间】:2015-05-11 18:25:39
【问题描述】:

我想更新动态生成的表列。

我试过了

ALTER PROCEDURE [dbo].[spname]
     @Id INT ,
     @Flag varchar(MAX),
     @TableName nvarchar(max) ,  
AS  
BEGIN    
    IF(@Flag='Process')  
    BEGIN   
    DECLARE @squery nvarchar(max) = ''

    IF EXISTS(SELECT NAME FROM [DZ_REPO].SYS.TABLES WHERE NAME = @TABLENAME)
        BEGIN
            set @squery = 'use [DZ_REPO]'
            set @squery += 'UPDATE A SET A.cFirstName=B.FN, A.cLastName=B.LN, A.cAddress=B.ADDR, A.cCity=B.CITY, A.cState=B.ST, A.cZIP=B.ZIP, 
            A.cGender=B.GENDER, A.cAge=B.EXACT_AGE, A.cHouseholdIncomeCode=B.HH_INCOME FROM [dbo].['+@TableName+'] as A, [Consumer].[dbo].[CONSUMERDB] as B 
            WHERE A.Email=B.Email AND A.AccountId =('+ @Id+')'          
            print (@squery)

            set @squery += 'UPDATE A SET A.cGender=B.[Value] FROM [dbo].['+@TableName+'] as A, [dbo].[abc] as B WHERE A.cGender=B.[Key] AND B.[Column]=N'Gender' AND A.AccountId = ('+@Id+')

            UPDATE A SET A.cHouseholdIncome=B.[Value] FROM [dbo].['+@TableName+'] as A, [dbo].[abc] as B WHERE A.cHouseholdIncomeCode=B.[Key] AND B.[Column]=('+HouseholdIncome+')  AND A.AccountId = ('+@Id+')

            UPDATE A SET A.cPresenceOfChild=B.[Value] FROM [dbo].['+@TableName+'] as A, [dbo].[abc] as B WHERE A.cPresenceOfChild=B.[Key] AND B.[Column]=('+PresenceOfChild+') AND A.AccountId = ('+@Id+')'
        END
    END  
END

但它给出了错误说明

消息 156,级别 15,状态 1,过程 spFileProcess,第 6 行不正确 关键字“AS”附近的语法。消息 102,级别 15,状态 1,程序 spFileProcess,第 26 行“性别”附近的语法不正确。消息 102,级别 15、状态 1、过程 spFileProcess、第 48 行附近的语法不正确 '假'

我编辑

ALTER PROCEDURE [dbo].[spname]
     @Id INT = 1 ,
     @Flag varchar(MAX) = 'Process',
     @TableName nvarchar(max) = 'SONY'  
AS  
BEGIN    
    IF(@Flag='Process')  
    BEGIN   
    DECLARE @squery nvarchar(max) = ''
    print ('call')
    IF EXISTS(SELECT NAME FROM [DZ_REPO].SYS.TABLES WHERE NAME = @TABLENAME)
        BEGIN
            set @squery = 'use [DZ_REPO]'
            print (@squery)
            set @squery += 'UPDATE A SET A.cFirstName=B.FN, A.cLastName=B.LN, A.cAddress=B.ADDR, A.cCity=B.CITY, A.cState=B.ST, A.cZIP=B.ZIP, 
            A.cGender=B.GENDER, A.cAge=B.EXACT_AGE, A.cHouseholdIncomeCode=B.HH_INCOME FROM [dbo].['+@TableName+'] as A, [Consumer].[dbo].[CONSUMERDB] as B 
            WHERE A.Email=B.Email AND A.AccountId =('+ @Id+')'          
            print (@squery)

            set @squery += 'UPDATE A SET A.cGender=B.[Value] FROM [dbo].['+@TableName+'] as A, [dbo].[abc] as B WHERE A.cGender=B.[Key] AND B.[Column]=N'Gender' AND A.AccountId = ('+@Id+')

            UPDATE A SET A.cHouseholdIncome=B.[Value] FROM [dbo].['+@TableName+'] as A, [dbo].[abc] as B WHERE A.cHouseholdIncomeCode=B.[Key] AND B.[Column]=('+HouseholdIncome+')  AND A.AccountId = ('+@Id+')

            UPDATE A SET A.cPresenceOfChild=B.[Value] FROM [dbo].['+@TableName+'] as A, [dbo].[abc] as B WHERE A.cPresenceOfChild=B.[Key] AND B.[Column]=('+PresenceOfChild+') AND A.AccountId = ('+@Id+')'
        END
    END  
END 

但是没有一个打印被调用并且错误抛出如下

消息 207,级别 16,状态 1,过程 spFileProcess,第 28 行 列名“性别”无效。 消息 207,级别 16,状态 1,过程 spFileProcess,第 30 行 列名“HouseholdIncome”无效。 消息 207,级别 16,状态 1,过程 spFileProcess,第 32 行 列名“PresenceOfChild”无效。

虽然这个 coumn 已经在 mt 表中了

有什么办法吗?

【问题讨论】:

  • 你的错误是什么,请在你的问题中发布
  • Msg 156,级别 15,状态 1,过程 spFileProcess,第 6 行关键字“AS”附近的语法不正确。消息 102,级别 15,状态 1,过程 spFileProcess,第 26 行“性别”附近的语法不正确。消息 102,级别 15,状态 1,过程 spFileProcess,第 48 行 'False' 附近的语法不正确。
  • 能否请您显示表 A 和 B 的架构。在我看来,两个表中都不存在必需的列。

标签: sql-server stored-procedures


【解决方案1】:

第一个 Update 语句和第二个 Update 语句之间需要空格。

...A.AccountId =('+ @Id+')' and set @squery += 'UPDATE A....

应该改成

...A.AccountId =('+ @Id+')' and set @squery += ' UPDATE A...

如果你在dynamic Sql execution 之前print 将很容易调试。您在中间打印@squery,即使在此之后您要附加更新语句,所以最好在print 上,并在附加所有update statements 后检查。

varchar 列值也应该用single quotes 括起来。

确保将传递给所有variables,否则@squery 将成为NULL

set @squery = 'use [DZ_REPO]'

set @squery += 'UPDATE A SET A.cFirstName=B.FN, A.cLastName=B.LN, A.cAddress=B.ADDR, A.cCity=B.CITY, A.cState=B.ST, A.cZIP=B.ZIP, 
            A.cGender=B.GENDER, A.cAge=B.EXACT_AGE, A.cHouseholdIncomeCode=B.HH_INCOME FROM [dbo].['+@TableName+'] as A, [Consumer].[dbo].[CONSUMERDB] as B 
            WHERE A.Email=B.Email AND A.AccountId =('+ @Id+')'          
            print (@squery)

 set @squery += 'UPDATE A SET A.cGender=B.[Value] FROM [dbo].['+@TableName+'] as A, [dbo].[abc] as B 
                WHERE A.cGender=B.[Key] 
                AND B.[Column]=N'''Gender''' --Here
                AND A.AccountId = ('+@Id+')

 UPDATE A SET A.cHouseholdIncome=B.[Value] FROM [dbo].['+@TableName+'] as A, [dbo].[abc] as B 
 WHERE A.cHouseholdIncomeCode=B.[Key] 
 AND B.[Column]=('''+HouseholdIncome+''')  
 AND A.AccountId = ('+@Id+')

 UPDATE A SET A.cPresenceOfChild=B.[Value] FROM [dbo].['+@TableName+'] as A, [dbo].[abc] as B 
 WHERE A.cPresenceOfChild=B.[Key] 
 AND B.[Column]=('''+PresenceOfChild+''') --here
 AND A.AccountId = ('+@Id+')'

【讨论】:

  • 当我在你建议的编辑后执行时,我得到了这样的错误,“消息 156,级别 15,状态 1,过程 spFileProcess,第 6 行关键字'AS'附近的语法不正确。消息 102,级别15,状态 1,过程 spFileProcess,第 26 行“性别”附近的语法不正确。消息 102,级别 15,状态 1,过程 spFileProcess,第 48 行“假”附近的语法不正确。”
  • 将打印语句放在动态执行之前,也没有打印出来
  • @KinjalPatel 确保将传递给所有variables,否则@squery将成为NULL
【解决方案2】:

我认为你需要像这样在查询字符串中添加空格

set @squery = 'use [DZ_REPO] '
set @squery += 'UPDATE A SET A.cFirstName......'

然后删除,@TableName nvarchar(max)

【讨论】:

    【解决方案3】:

    用评论检查这个 sql(这是你的第一个 sql 帖子):

    ALTER PROCEDURE [dbo].[spname]
         @Id INT ,
         @Flag varchar(MAX),
         @TableName nvarchar(max),  --remove comma from here
    AS  
    BEGIN    
        IF(@Flag='Process')  
        BEGIN   
        DECLARE @squery nvarchar(max) = ''
    
        IF EXISTS(SELECT NAME FROM master.SYS.TABLES WHERE NAME = @TABLENAME)
            BEGIN
                set @squery = 'use [DZ_REPO]'
                set @squery += 'UPDATE A SET A.cFirstName=B.FN, A.cLastName=B.LN, A.cAddress=B.ADDR, A.cCity=B.CITY, A.cState=B.ST, A.cZIP=B.ZIP, 
                A.cGender=B.GENDER, A.cAge=B.EXACT_AGE, A.cHouseholdIncomeCode=B.HH_INCOME FROM [dbo].['+@TableName+'] as A, [Consumer].[dbo].[CONSUMERDB] as B 
                WHERE A.Email=B.Email AND A.AccountId =('+ @Id+')'          
                print (@squery)
    
                --if 'Gender' id your fixed column then give as below with double comma
                --HouseholdIncome - where you define this variable and assign it
                --PresenceOfChild - where you define this variable and assign it
                set @squery += 'UPDATE A SET A.cGender=B.[Value] FROM [dbo].['+@TableName+'] as A, [dbo].[abc] as B WHERE A.cGender=B.[Key] AND B.[Column]=N''Gender'' AND A.AccountId = ('+@Id+')
    
                UPDATE A SET A.cHouseholdIncome=B.[Value] FROM [dbo].['+@TableName+'] as A, [dbo].[abc] as B WHERE A.cHouseholdIncomeCode=B.[Key] AND B.[Column]=('+HouseholdIncome+')  AND A.AccountId = ('+@Id+')
    
                UPDATE A SET A.cPresenceOfChild=B.[Value] FROM [dbo].['+@TableName+'] as A, [dbo].[abc] as B WHERE A.cPresenceOfChild=B.[Key] AND B.[Column]=('+PresenceOfChild+') AND A.AccountId = ('+@Id+')'
            END
        END  
    END
    

    【讨论】:

      【解决方案4】:

      第一个错误:从@TableName nvarchar(max) 变量的末尾删除逗号(,)。 第二个错误:如果您要在其上传递一些动态值,则需要声明 Gender、HouseholdIncome、HouseholdIncome、PresenceOfChild。或者如果这是列名,则从中删除 +(加号)。

      例如: AND B.[Column]=(HouseholdIncome)

      【讨论】:

      • 我会尝试这样并得到类似“转换 nvarchar 值时转换失败'使用 [DZ_REPO] UPDATE A SET A.cFirstName=B.FN, A.cLastName=B. LN,A.cAddress=B.ADDR,A.cCity=B.CITY,A.cState=B.ST,A.cZIP=B.ZIP,A.cGender=B.GENDER,A.cAge=B.EXACT_AGE, A.cHouseholdIncomeCode=B.HH_INCOME FROM [dbo].[SONY] as A, [Consumer].[dbo].[CONSUMERDB] as B WHERE A.Email=B.Email AND A.Picked 为 NULL AND A.DataProfilingAccountId = ('+ @Id+')' 转换为数据类型 int。"
      • 使用这个 A.DataProfilingAccountId =( @Id)
      猜你喜欢
      • 1970-01-01
      • 2021-03-03
      • 2021-06-22
      • 2021-03-07
      • 1970-01-01
      • 2019-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多