使用特定表为所有数据库创建动态存储过程

时间:2017-02-21 12:23:30

标签: sql-server stored-procedures

我想将以下存储过程添加到包含表schichten的所有现有数据库中。我所有的方法都失败了,所以我在这里寻求帮助。

这是我的方法:

IF object_id('tempdb.dbo.#database') is not null 
    drop TABLE #database
GO

CREATE TABLE #database(id INT identity primary key, name sysname)
GO

SET NOCOUNT ON

INSERT INTO #database(name)
    SELECT name 
    FROM sys.databases 
    WHERE source_database_id is null 
    ORDER BY name

SELECT * FROM #database

DECLARE @id INT, @cnt INT, @sql NVARCHAR(MAX), @currentDb SYSNAME;

SELECT @id = 1, @cnt = max(id) FROM #database

WHILE @id <= @cnt
BEGIN
    BEGIN TRY
        SELECT @currentDb = name 
        FROM #database 
        WHERE id = @id

        IF OBJECT_ID(@currentDb+'.dbo.schichten') IS NOT NULL
            CREATE PROCEDURE @currentDb.[dbo].[Ausw_Tabelle_Taxi_Pers_Jahr] 
                @ColumnName nvarchar(MAX), 
                @Selector nvarchar(MAX), 
                @Gesamtergebnis nvarchar(MAX)
            AS
            BEGIN
                SET NOCOUNT ON;

                DECLARE @sql1  AS NVARCHAR(MAX),
                        @ASSelector nvarchar(MAX),
                        @IFPers nvarchar(MAX);

                IF @Selector = 'konz'
                BEGIN
                    SET @ASSelector = 'Taxi'
                    SET @IFPers=''
                END
                ELSE
                BEGIN
                    SET @ASSelector = 'Personal'
                    SET @IFPers = '[name] AS Name,'
                END

                SET @sql1 = N';WITH temp AS (SELECT *
                        FROM (
   SELECT
          ISNULL((DATENAME(m,[datum])+ cast(datepart(yyyy,[datum]) as varchar(5))),0) AS MONTHYEAR,
          ISNULL(['+ @Selector +'],0) AS '+ @ASSelector +','+ @IFPers +'              
          ISNULL((ISNULL([umsum],0) +
                          ISNULL([sonst_0],0) +
                          ISNULL([sonst_7],0) +
                          ISNULL([sonst_16],0) +
                          ISNULL([sonst_z],0) -
                          ISNULL([ff],0)),0)        AS UMSATZSUMME 

   FROM [dbo].[schichten]

   ) AS SOURCE
  PIVOT (SUM([UMSATZSUMME]) FOR [MONTHYEAR] IN ('+ @ColumnName + N' )) AS UMSAETZE ) 
SELECT *, '+ @Gesamtergebnis +'  AS Gesamtergebnis FROM temp ORDER BY '+ @ASSelector +''

EXEC sp_executesql @sql

END

END TRY
BEGIN CATCH
END CATCH

SET @id = @id + 1;

END

GO

我希望有人可以帮助我。

2 个答案:

答案 0 :(得分:0)

你必须单独执行create procedure,所以如果你将它包装成变量并使用exec sp_executesql它应该可以工作。

IF object_id('tempdb.dbo.#database') is not null 
    drop TABLE #database
GO

CREATE TABLE #database(id INT identity primary key, name sysname)
GO

SET NOCOUNT ON

INSERT INTO #database(name)
    SELECT name 
    FROM sys.databases 
    WHERE source_database_id is null 
    ORDER BY name

SELECT * FROM #database

DECLARE @id INT, @cnt INT, @sql NVARCHAR(MAX), @currentDb SYSNAME;

SELECT @id = 1, @cnt = max(id) FROM #database

WHILE @id <= @cnt
BEGIN
    BEGIN TRY
        SELECT @currentDb = name 
        FROM #database 
        WHERE id = @id

        IF OBJECT_ID(@currentDb+'.dbo.schichten') IS NOT NULL
        begin
            set @sql = 'CREATE PROCEDURE '+@currentDb+'.[dbo].[Ausw_Tabelle_Taxi_Pers_Jahr] 
                @ColumnName nvarchar(MAX), 
                @Selector nvarchar(MAX), 
                @Gesamtergebnis nvarchar(MAX)
            AS
            BEGIN
                SET NOCOUNT ON;

                DECLARE @sql1  AS NVARCHAR(MAX),
                        @ASSelector nvarchar(MAX),
                        @IFPers nvarchar(MAX);

                IF @Selector = ''konz''
                BEGIN
                    SET @ASSelector = ''Taxi''
                    SET @IFPers=''''
                END
                ELSE
                BEGIN
                    SET @ASSelector = ''Personal''
                    SET @IFPers = ''[name] AS Name,''
                END

                SET @sql1 = N'';WITH temp AS (SELECT *
                        FROM (
   SELECT
          ISNULL((DATENAME(m,[datum])+ cast(datepart(yyyy,[datum]) as varchar(5))),0) AS MONTHYEAR,
          ISNULL([''+ @Selector +''],0) AS ''+ @ASSelector +'',''+ @IFPers +''              
          ISNULL((ISNULL([umsum],0) +
                          ISNULL([sonst_0],0) +
                          ISNULL([sonst_7],0) +
                          ISNULL([sonst_16],0) +
                          ISNULL([sonst_z],0) -
                          ISNULL([ff],0)),0)        AS UMSATZSUMME 

   FROM [dbo].[schichten]

   ) AS SOURCE
  PIVOT (SUM([UMSATZSUMME]) FOR [MONTHYEAR] IN (''+ @ColumnName + N'' )) AS UMSAETZE ) 
SELECT *, ''+ @Gesamtergebnis +''  AS Gesamtergebnis FROM temp ORDER BY ''+ @ASSelector +''''

EXEC sp_executesql @sql1

END'
EXEC sp_executesql @sql
END TRY
BEGIN CATCH
END CATCH

SET @id = @id + 1;

END

GO

答案 1 :(得分:0)

假设这是一次性需求而不是夜间维护任务,您可以使用内置存储过程sys.sp_MSforeachdb来在每个数据库中执行语句。它使用安全,并已在网上广泛讨论。但是,它是一个未记录的功能,可以在不事先通知的情况下删除,因此您不希望依赖它来执行重复任务。

在一个数据库中创建并验证您的语句,然后使用此存储过程在所有数据库中执行它。 ?是数据库名称的占位符。

EXEC sys.sp_MSforeachdb @command1 = 
  'IF OBJECT_ID(''?.dbo.schichten'') IS NOT NULL
   AND OBJECT_id(''?.[dbo].[Ausw_Tabelle_Taxi_Pers_Jahr]'') IS NOT NULL
BEGIN
CREATE PROCEDURE ?.[dbo].[Ausw_Tabelle_Taxi_Pers_Jahr] 
                @ColumnName nvarchar(MAX), 
                @Selector nvarchar(MAX), 
                @Gesamtergebnis nvarchar(MAX)
            AS
            BEGIN
                SET NOCOUNT ON;

                DECLARE @sql1  AS NVARCHAR(MAX),
                        @ASSelector nvarchar(MAX),
                        @IFPers nvarchar(MAX);

                IF @Selector = ''konz''
                BEGIN
                    SET @ASSelector = ''Taxi''
                    SET @IFPers=''''
                END
                ELSE
                BEGIN
                    SET @ASSelector = ''Personal''
                    SET @IFPers = ''[name] AS Name,''
                END

                SET @sql1 = N'';WITH temp AS (SELECT *
                        FROM (
   SELECT
          ISNULL((DATENAME(m,[datum])+ cast(datepart(yyyy,[datum]) as varchar(5))),0) AS MONTHYEAR,
          ISNULL([''+ @Selector +''],0) AS ''+ @ASSelector +'',''+ @IFPers +''              
          ISNULL((ISNULL([umsum],0) +
                          ISNULL([sonst_0],0) +
                          ISNULL([sonst_7],0) +
                          ISNULL([sonst_16],0) +
                          ISNULL([sonst_z],0) -
                          ISNULL([ff],0)),0)        AS UMSATZSUMME 

   FROM [dbo].[schichten]

   ) AS SOURCE
  PIVOT (SUM([UMSATZSUMME]) FOR [MONTHYEAR] IN (''+ @ColumnName + N'' )) AS UMSAETZE ) 
SELECT *, ''+ @Gesamtergebnis +''  AS Gesamtergebnis FROM temp ORDER BY ''+ @ASSelector +''''

EXEC sp_executesql @sql1

END
'