简体   繁体   中英

Invalid column name when trying to drop schema/user using SQL script

What I'm trying to accomplish is to remove any extra users/schemas (anything listed in NOT IN I want to keep). I can't blanket remove the users in case they are attached to any schemas by the same name (some are like that, some aren't), so I'm trying to check to see if the schema I want to remove exists, if it does, then I want to remove it. I want to do the same for any users attached to databases using the same logic.

My problem is when I run the script, it finds the users/schemas I want to remove but it throws an error saying "Invalid column name 'USERNAME HERE'.

Any ideas?

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)

For anyone curious I got this working using a cursor.

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

I had to include the WAITFOR DELAY because whenever it tried to drop the user, SQL was still saying it was associated with a schema.

Are you using " (Double quotation) or '' (two single quotations) for escaping the quotation mark? It looks if you're using the double quotation mark which is not right. It should be:

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM