I'm trying to find the best way to execute a query against all databases on the server using SQLServerAgent or maintenance plan.
I have a stored procedure that I'd like to run on these databases, but I cannot create the stored procedure in these databases.
I tried experimenting with using exec sp_msforeachdb
and DECLARE @command = '<my sp>'
but I ran into the problem with escaping too many single quotes '.
So in the end, I'd like to say something like:
For all databases, run this block of code. Then schedule this job with SQLServerAgent.
BEGIN
SET NOCOUNT ON
--DECLARE VARIABLES
DECLARE
@max INT,
@min INT,
@table_name NVARCHAR(256),
@table_schema NVARCHAR(256),
@sql NVARCHAR(4000)
--DECLARE TABLE VARIABLE
DECLARE @table TABLE(
id INT IDENTITY(1,1) PRIMARY KEY,
table_name NVARCHAR(256),
table_schema NVARCHAR(256))
--CREATE TEMP TABLE THAT STORES INFORMATION FROM SP_SPACEUSED
IF (SELECT OBJECT_ID('tempdb..#results')) IS NOT NULL
BEGIN
DROP TABLE #results
END
CREATE TABLE #results
(
[database_id] [int] NULL,
[server_name] [nvarchar](256) NULL, --- new, server name
[database_name] [nvarchar](256) NULL, --- new, db name
[table_schema] [nvarchar](256) NULL,
[table_name] [nvarchar](256) NULL,
[table_rows] [int] NULL,
[reserved_space] [nvarchar](55) NULL,
[data_space] [nvarchar](55) NULL,
[index_space] [nvarchar](55) NULL,
[unused_space] [nvarchar](55) NULL
)
--LOOP THROUGH STATISTICS FOR EACH TABLE
INSERT @table(table_schema, table_name)
SELECT
table_schema, table_name
FROM
information_schema.tables
SELECT
@min = 1,
@max = (SELECT MAX(id) FROM @table)
WHILE @min <= @max
BEGIN
SELECT
@table_name = table_name,
@table_schema = table_schema
FROM
@table
WHERE
id = @min
--DYNAMIC SQL
SELECT @sql = 'EXEC sp_spaceused ''[' + @table_schema + '].[' + @table_name + ']''' --get dataA
--INSERT RESULTS FROM SP_SPACEUSED TO TEMP TABLE
INSERT #results(table_name, table_rows, reserved_space, data_space, index_space, unused_space)
EXEC (@sql) --set dataA^
--UPDATE SCHEMA NAME
UPDATE #results
SET table_schema = @table_schema WHERE table_name = @table_name
UPDATE #results
SET
database_id = (DB_ID()),
server_name = (select @@SERVERNAME),
database_name = (SELECT DB_NAME() AS [Current Database]);
SELECT @min = @min + 1
END
--REMOVE "KB" FROM RESULTS FOR REPORTING (GRAPH) PURPOSES
UPDATE #results SET data_space = SUBSTRING(data_space, 1, (LEN(data_space)-3))
UPDATE #results SET reserved_space = SUBSTRING(reserved_space, 1, (LEN(reserved_space)-3))
UPDATE #results SET index_space = SUBSTRING(index_space, 1, (LEN(index_space)-3))
UPDATE #results SET unused_space = SUBSTRING(unused_space, 1, (LEN(unused_space)-3))
--INSERT RESULTS INTO TABLESIZEGROWTH
INSERT INTO TableSizes.dbo.TableSizeGrowth (database_id, server_name, database_name, table_schema, table_name, table_rows, reserved_space, data_space, index_space, unused_space)
SELECT * FROM #results
DROP TABLE #results
END
Best Answer
Create a SQL Agent Job with a Job Step of type "Powershell" on the SQL Server instance where your databases reside.
Schedule it like any other job.