Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在另一个数据库中动态创建函数_Sql_Sql Server_Sql Server 2008_Tsql_Sql Server 2012 - Fatal编程技术网

Sql 在另一个数据库中动态创建函数

Sql 在另一个数据库中动态创建函数,sql,sql-server,sql-server-2008,tsql,sql-server-2012,Sql,Sql Server,Sql Server 2008,Tsql,Sql Server 2012,当我在master上时,我试图在每个数据库上创建函数, 我用的是游标 DECLARE c_db_names CURSOR FOR SELECT name FROM sys.databases WHERE name NOT IN('master','model','msdb','tempdb','ReportServer$SQLEXPRESS','ReportServer$SQLEXPRESSTempDB') OPEN c_db_names

当我在master上时,我试图在每个数据库上创建函数, 我用的是游标

DECLARE c_db_names CURSOR FOR
      SELECT name 
      FROM sys.databases
       WHERE name NOT IN('master','model','msdb','tempdb','ReportServer$SQLEXPRESS','ReportServer$SQLEXPRESSTempDB') 
      OPEN c_db_names
      FETCH next from c_db_names INTO @db_name

      WHILE @@Fetch_Status = 0
      BEGIN

      set @sql = 'Create function...'

set @UseAndExecStatment = 'use ' + @db_name + ' exec sp_executesql '+@sql

        exec Sp_executeSql @UseAndExecStatment
        FETCH next from c_db_names INTO @db_name
      END
      CLOSE c_db_names
      DEALLOCATE c_db_names
问题是它不起作用,它说: CREATE FUNCTION“必须是查询批处理中的第一条语句

有什么想法吗?
谢谢您的帮助。

您可以改用db..sp\u executesql:

declare @sql nvarchar(max), @db_name nvarchar(max), @sql2 nvarchar(max)

DECLARE c_db_names CURSOR FOR
      SELECT name 
      FROM sys.databases
       WHERE name NOT IN('master','model','msdb','tempdb','ReportServer$SQLEXPRESS','ReportServer$SQLEXPRESSTempDB') 
       and name ='reports'
      OPEN c_db_names
      FETCH next from c_db_names INTO @db_name

      WHILE @@Fetch_Status = 0
      BEGIN

      set @sql2 = 'create procedure ...'
      set @sql = 'exec '+@db_name+'..sp_executesql N''' + @sql2+''''

        print @sql
        --exec(@sql)
        FETCH next from c_db_names INTO @db_name
      END
      CLOSE c_db_names
      DEALLOCATE c_db_names

在createquery中定义数据库

试一试

见:

set@sql='Create function'+@db_name+'dbo.functionName…'

完成:

declare @sql nvarchar(max), @db_name nvarchar(max), @sql2 nvarchar(max)
declare @sp_executesql nvarchar (max)
DECLARE c_db_names CURSOR FOR
      SELECT name 
      FROM sys.databases
       WHERE name NOT IN('master','model','msdb','tempdb','ReportServer$SQLEXPRESS','ReportServer$SQLEXPRESSTempDB') 
       --and name ='reports'
      OPEN c_db_names
      FETCH next from c_db_names INTO @db_name

      WHILE @@Fetch_Status = 0
      BEGIN


      set @sql2 = N'
CREATE FUNCTION [String_Turn_Month]  (@d char(6))
RETURNS char(6)
AS
BEGIN 
DECLARE @#DSTR char(6)
IF @D=''''000000''''
set @#dstr=''''000000''''
IF substring(@d,3,4)<1800
RETURN(@D)
IF substring(@d,3,4)>1800
set @#dstr=cast(substring(@d,3,4)+substring(@d,1,2) as char(6))
RETURN(@#DSTR)
END'
  --  set @sql = 'exec '+@db_name+'..sp_executesql N''' + @sql2+''''

  set @sp_executesql = 'exec ' + @db_name + '..sp_executeSQL N''' + @sql2 + ''''
  PRINT @sp_executesql
    EXEC sp_executeSQL   @sp_executesql

        print '------------'
        print '------------'
        print '------------'

     --   exec(@sql)
        FETCH next from c_db_names INTO @db_name
      END
      CLOSE c_db_names
      DEALLOCATE c_db_names

在USE DB命令后添加GO这个词。尝试使用GO命令将语句分为两批。将它放在“Create function”之前。尝试将它改为b4,在“go”附近使用不正确的语法。它不适用于go。问题是,无论将go放在何处,错误都会出现,“CREATE FUNCTION”必须是查询批处理中的第一条语句。这是一个好问题,因为正如JiggsJedi所示,我们可以在一条游标语句中在不同的数据库中执行命令。直到现在我才认为这是可能的。在sp_executeSqlI中不能使用“GO”。谢谢,我已经更新了样本来说明这一点。您的解决方案运行良好。但在一种情况下,当我的DB名称中有“-”时,比如我的DB,它会在“DB”附近抛出错误Msg 102,级别15,状态1,第1行不正确的语法。
declare @sql nvarchar(max), @db_name nvarchar(max), @sql2 nvarchar(max)
declare @sp_executesql nvarchar (max)
DECLARE c_db_names CURSOR FOR
      SELECT name 
      FROM sys.databases
       WHERE name NOT IN('master','model','msdb','tempdb','ReportServer$SQLEXPRESS','ReportServer$SQLEXPRESSTempDB') 
       --and name ='reports'
      OPEN c_db_names
      FETCH next from c_db_names INTO @db_name

      WHILE @@Fetch_Status = 0
      BEGIN


      set @sql2 = N'
CREATE FUNCTION [String_Turn_Month]  (@d char(6))
RETURNS char(6)
AS
BEGIN 
DECLARE @#DSTR char(6)
IF @D=''''000000''''
set @#dstr=''''000000''''
IF substring(@d,3,4)<1800
RETURN(@D)
IF substring(@d,3,4)>1800
set @#dstr=cast(substring(@d,3,4)+substring(@d,1,2) as char(6))
RETURN(@#DSTR)
END'
  --  set @sql = 'exec '+@db_name+'..sp_executesql N''' + @sql2+''''

  set @sp_executesql = 'exec ' + @db_name + '..sp_executeSQL N''' + @sql2 + ''''
  PRINT @sp_executesql
    EXEC sp_executeSQL   @sp_executesql

        print '------------'
        print '------------'
        print '------------'

     --   exec(@sql)
        FETCH next from c_db_names INTO @db_name
      END
      CLOSE c_db_names
      DEALLOCATE c_db_names