We help IT Professionals succeed at work.

SQLCMD Mode Script Executing on Multiple Schemas

So we have a database where each client are their own schema.  Each schema has the same set of tables.  I need to be able to automate running an update script on each schema's set of tables.  Currently the script is executed while in sqlcmd mode where a variable is set to a schema.  There is a table that has a list of all the clients and their schemas, so is there a way to query this list and execute this script for each schema?

SQL Server 2016 Standard 13.0.5233.0

Thank you for your time.
Comment
Watch Question

Marcus KeustermansSolutions Architect

Commented:
Hi

Put the client and schema information into a temp or in memory table
Loop through the table by taking the first record execute some dynamic sql that takes the values from the record then   delete the record  it when you are done executing code something like this:

DECLARE @ClientSchema TABLE( client varchar(50), clientSchema varchar(50))
DECLARE @someRandomFilter VARCHAR(50) = 'Filter'

Insert into @ClientSchema(client,clientSchema)
SELECT client,clientSchema from clientSchemaTable

DECLARE @client varchar(50)
DECLARE @clientSchema VARCHAR(50)
DECLARE @sql NVARCHAR(MAX)

SELECT TOP 1 @client = client, @clientSchema = clientSchema FROM clientSchemaTable

WHILE @clientSchema IS NOT NULL
BEGIN
	SET @sql = 'DELETE FROM ' + @schema + '.TableName where column1 = ' + @someRandomFilter

	exec(@pivotSql)


	DELETE FROM @ClientSchema where client = @client and clientSchema = @clientSchema

	SET @client = NULLSET @ClientSchema = NULL
	SELECT TOP 1 @client = client, @clientSchema = clientSchema FROM clientSchemaTable
END

Open in new window

Author

Commented:
Hi Marcus,

thank you for your help.  So if I'm understanding you correctly, all the scripts that are doing some altering of tables or data need to be change to dynamic sql?

Here is an example of what is in this db update script:

DECLARE @GUID UNIQUEIDENTIFIER
------------------------------------------
SET @GUID = '{12D4BEEC-2825-4949-A356-48716F0142C8}'

------------------------------------------
IF (SELECT COUNT(*) FROM [$(SchemaName)].tblSchemaEvolution WHERE ChangeID = @GUID) = 0
BEGIN

PRINT 'Applying update ' + convert(nvarchar(max), @GUID)

UPDATE [$(SchemaName)].DealCustomMetaData SET DefaultLabel='Employees' WHERE FieldName='SR_Employees'
UPDATE [$(SchemaName)].DealCustomMetaData SET DefaultLabel='Locations' WHERE FieldName='SR_Locations'

INSERT INTO [$(SchemaName)].tblSchemaEvolution (ChangeID) VALUES (@GUID)

END
GO
Marcus KeustermansSolutions Architect

Commented:
thank you for your help.  So if I'm understanding you correctly, all the scripts that are doing some altering of tables or data need to be change to dynamic sql?

I suggest that you create a stored procedure and put your update code in there. and then call the stored procedure from a scheduling tool or SSIS or whichever automation mechanism your are using

It could look like the following.

CREATE PROCEDURE dbo.UpdateProcedure
@guid VARCHAR(50)
AS
BEGIN
	DECLARE @ClientSchema TABLE (client VARCHAR(50),clientSchema VARCHAR(50))
	INSERT INTO @ClientSchema(client,clientSchema)
	SELECT client,clientSchema from clientSchemaTable

	DECLARE @client varchar(50)
	DECLARE @clientSchema VARCHAR(50)
	DECLARE @sql NVARCHAR(MAX)

	SELECT TOP 1 @client = client, @clientSchema = clientSchema FROM clientSchemaTable

	WHILE @clientSchema IS NOT NULL
	BEGIN

		SET @sql = '

		UPDATE [' + @clientSchema + '].DealCustomMetaData SET DefaultLabel=''Employees'' WHERE FieldName=''SR_Employees''
	
		UPDATE [' + @clientSchema +'].DealCustomMetaData SET DefaultLabel=''Locations'' WHERE FieldName=''SR_Locations''

		INSERT INTO [' + @clientSchema + '].tblSchemaEvolution (ChangeID) VALUES(''' + @guid + ''')'

		exec(@sql)


		DELETE FROM @ClientSchema where client = @client and clientSchema = @clientSchema

		SET @client = NULL
                SET @ClientSchema = NULL

		SELECT TOP 1 @client = client, @clientSchema = clientSchema FROM clientSchemaTable
	END
END

Open in new window

Author

Commented:
ok, so dynamic sql is the only option.  It is a very large script file and converting it to dynamic sql will definitely take a lot of time.

Thanks for your help.
Commented:
So I figured out how to execute sqlcmd from code or from ssis and pass variable values.  Will be automating the execution of the script file per schema and not changing it to dynamic sql.

Thank you for your help on this.