【问题标题】:Invalid column name when trying to drop schema/user using SQL script尝试使用 SQL 脚本删除架构/用户时列名无效
【发布时间】:2023-03-03 01:48:02
【问题描述】:

我想要完成的是删除任何额外的用户/模式(我想保留的 NOT IN 中列出的任何内容)。如果用户以相同的名称附加到任何模式(有些是这样,有些不是),我不能一概删除用户,所以我试图检查我要删除的模式是否存在,如果是这样,那么我想删除它。我想对使用相同逻辑连接到数据库的任何用户执行相同操作。

我的问题是,当我运行脚本时,它找到了我想要删除的用户/模式,但它抛出了一个错误,提示“列名 'USERNAME HERE' 无效。

有什么想法吗?

declare @sql nvarchar(max)
set @sql = ''

SELECT @sql = @sql+
'
IF EXISTS (SELECT NAME FROM sys.schemas WHERE NAME = "'+ name +'" )
BEGIN
   DROP SCHEMA "'+ name +'"
END

IF EXISTS (SELECT NAME FROM dbo.sysusers WHERE NAME = "'+ name +'" )
BEGIN
   DROP USER "'+ name +'"
END
'

FROM
    dbo.sysusers
WHERE
    name NOT IN('dbo','guest','INFORMATION_SCHEMA','sys','public')
    AND LEFT(name,3) <> 'db_'
order by
    name

execute ( @sql )
--print (@sql)

【问题讨论】:

    标签: sql sql-server schema


    【解决方案1】:

    对于任何好奇的人,我使用光标来完成这项工作。

    DECLARE @UserName varchar(256)
    DECLARE @sqlSchema varchar(100)
    DECLARE @sqlUser varchar(100)
    
    DECLARE csrUser CURSOR FOR
    SELECT [name] FROM sys.database_principals WHERE name 
        NOT IN('dbo','guest','INFORMATION_SCHEMA','sys','public') AND LEFT(name,3) <> 'db_'
        ORDER BY [name]
    
    OPEN csrUser
    
    FETCH NEXT FROM csrUser INTO @UserName
    
    WHILE @@FETCH_STATUS <> -1
    BEGIN
    
        IF EXISTS(SELECT NAME FROM sys.schemas WHERE NAME = @userName )
        BEGIN
            set @sqlSchema = 'drop schema "' + @userName + '"'
            print @sqlSchema
            --exec (@sqlSchema)
            WAITFOR DELAY '00:00:05'
        END
    
        set @sqlUser = 'drop user "' + @userName + '"'
        print @sqlUser
        --exec (@sqlUser)
    
        FETCH NEXT FROM csrUser INTO @UserName
    END
    
    CLOSE csrUser
    DEALLOCATE csrUser
    

    我必须包含 WAITFOR DELAY,因为每当它试图删除用户时,SQL 仍然说它与一个模式相关联。

    【讨论】:

      【解决方案2】:

      你是用"(双引号)还是''(两个单引号)来转义引号?看起来你是否使用了不正确的双引号。 应该是:

      declare @sql nvarchar(max)
      set @sql = ''
      
      SELECT @sql = @sql+
      '
      IF EXISTS (SELECT NAME FROM sys.schemas WHERE NAME = '''+ name +''' )
      BEGIN
         DROP SCHEMA '''+ name +'''
      END
      
      IF EXISTS (SELECT NAME FROM dbo.sysusers WHERE NAME = '''+ name +''' )
      BEGIN
         DROP USER '''+ name +'''
      END
      '
      
      FROM
          dbo.sysusers
      WHERE
          name NOT IN('dbo','guest','INFORMATION_SCHEMA','sys','public')
          AND LEFT(name,3) <> 'db_'
      order by
          name
      
      --execute ( @sql )
      print (@sql)
      

      【讨论】:

      • 我使用双引号。我要清理的用户是旧服务帐户,名称类似于“domain\svc_something-something”。如果我尝试使用三个单引号,我会收到一条错误消息,指出“'DOMAIN\user' 附近的语法不正确
      猜你喜欢
      • 1970-01-01
      • 2016-08-24
      • 1970-01-01
      • 2017-10-11
      • 1970-01-01
      • 2018-05-07
      • 1970-01-01
      • 1970-01-01
      • 2021-08-15
      相关资源
      最近更新 更多