【问题标题】:Create a dynamic query创建动态查询
【发布时间】:2017-04-20 14:47:23
【问题描述】:

我做了一个这样的存储过程..

CREATE PROCEDURE [dbo].[sp_dataPull] @serverName nvarchar(30), @dbName nvarchar (30), @serverName2 nvarchar(30), @dbName2 nvarchar (30)

    INSERT INTO sampleDatabase.dbo.WorkFlowCopy
      ([ServerName]
      ,[DBName]
      ,[ID]
      ,[ActivityDefinitionID]
      ,[ParentID]
      ,[Caption]
      ,[Description]
      ,[ShortDescription]

(SELECT @serverName, @dbName, sdb1.* from OPENDATASOURCE('SQLOLEDB',
'Data Source=phmnldb16\eaudit;user id=XXXX;password=XXXX').AUDIT_FSA_170_001.AUD170.Workflow sdb1)

UNION ALL

(SELECT @serverName2, @dbName2, sdb2.* from OPENDATASOURCE('SQLOLEDB',
'Data Source=phmnldb16\eaudit;user id=XXXX;password=XXXX').AUDIT_FSA_170_002.AUD170.Workflow sdb2)

此查询的功能是将数据从另一台服务器移动到特定的表中。现在,请注意下面有 2 个 SELECT 语句,并且有 4 个参数。这是因为我合并了 2 个表并把它移到了另一个表中。

这个查询的问题在于它是静态的。如果我需要合并 3 个或更多表怎么办?然后我必须创建另一个(下面的 SELECT 和 UNION ALL 语句并添加另外 2 个或更多参数)。我想让它成为 DYNAMIC。

【问题讨论】:

  • 您的语法看起来像 SQL Server。为什么问题标记为 Oracle?
  • 你好,戈登,它是 SQL Server。但我标记了 5 个不同的名称作为堆栈溢出需要。
  • 不需要标记5
  • 使用光标循环浏览服务器和数据库名称列表。您可以传入表格参数或逗号分隔列表,并使用拆分字符串函数将其放入表格中。
  • 旁注:您应该为您的存储过程使用sp_ 前缀。微软有reserved that prefix for its own use (see Naming Stored Procedures),你确实会在未来某个时候冒着名称冲突的风险。 It's also bad for your stored procedure performance。最好只是简单地避免 sp_ 并使用其他东西作为前缀 - 或者根本不使用前缀!

标签: sql sql-server database dynamic


【解决方案1】:

尝试如下:

CREATE PROCEDURE SP_DATAPULL @SERVER NVARCHAR(30),@DB NVARCHAR(30)
AS 
BEGIN
DECLARE @SERVER NVARCHAR(MAX)='SERVER1,SERVER2,SERVER3,SERVER4,SERVER5'
DECLARE @DB NVARCHAR(MAX)='DB1,DB2,DB3,DB4,DB5'
DECLARE @SRV NVARCHAR(MAX),@DBN NVARCHAR(MAX),@QUERY NVARCHAR(MAX)
DECLARE @TEMP TABLE(SERVERNAME VARCHAR(100),DB VARCHAR(100))

WHILE(SELECT CHARINDEX(',',@SERVER))>0
BEGIN
SET @SRV=(SELECT SUBSTRING(@SERVER,0,CHARINDEX(',',@SERVER)))
SET @SERVER=SUBSTRING(@SERVER,LEN(@SRV)+2,LEN(@SERVER))

SET @DBN=(SELECT SUBSTRING(@DB,0,CHARINDEX(',',@DB)))
SET @DB=SUBSTRING(@DB,LEN(@DBN)+2,LEN(@DB))
INSERT INTO @TEMP VALUES (@SRV,@DBN )
END
INSERT INTO @TEMP VALUES (@SERVER,@DB )

SET @QUERY=' INSERT INTO sampleDatabase.dbo.WorkFlowCopy
      ([ServerName]
      ,[DBName]
      ,[ID]
      ,[ActivityDefinitionID]
      ,[ParentID]
      ,[Caption]
      ,[Description]
      ,[ShortDescription] '

DECLARE C CURSOR FOR
SELECT SERVERNAME,DB FROM @TEMP
OPEN C
FETCH NEXT FROM C INTO @SERVER,@DB
WHILE @@FETCH_STATUS=0
BEGIN

SET @QUERY=@QUERY+'(SELECT '''+@SERVER+''', '''+@DB+''', sdb1.* from OPENDATASOURCE(''SQLOLEDB'',
''Data Source=phmnldb16\eaudit;user id=XXXX;password=XXXX'').AUDIT_FSA_170_001.AUD170.Workflow sdb1) '

FETCH NEXT FROM C INTO @SERVER,@DB
END
CLOSE C
DEALLOCATE C
SET @QUERY=SUBSTRING(@QUERY,0,LEN(@QUERY)-LEN('UNION ALL'))
PRINT @QUERY
EXEC(@QUERY)
END

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-12
    • 2015-10-01
    • 2015-04-09
    • 2011-12-02
    • 2011-02-18
    • 2020-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多