【问题标题】:Creating a database in MSSQL using SQL procedures使用 SQL 过程在 MSSQL 中创建数据库
【发布时间】:2018-04-03 07:19:10
【问题描述】:

您好,我正在尝试使用以下 SQL 过程创建数据库

Create_SQL_Proc_Statement = """
CREATE PROCEDURE db_creation_script
           @DBName nvarchar(50),
           @data_path nvarchar(50) ='',
           @data_file_size nvarchar(50) = '5000KB',
           @data_file_maxsize nvarchar(50) = 'UNLIMITED',
           @data_file_filegrowth nvarchar(50) = '1024KB',
           @log_path nvarchar(50) ='',
           @log_file_size nvarchar(50) = '5000KB',
           @log_file_maxsize nvarchar(50) = '1048576KB',
           @log_file_filegrowth nvarchar(50) = '1024KB'
AS

begin

           declare @l_variable_data as nvarchar(500);
           declare @l_variable_log as nvarchar(500);
           declare @complete_command as nvarchar(1000);
           declare @print_message as nvarchar(1000);
           declare @error as int;

           --Fetch data path

           if (@data_path ='' OR @data_path is null )
                          SELECT @data_path=cast(SERVERPROPERTY('InstanceDefaultDataPath') as nvarchar);
           if (@data_path ='' OR @data_path is null )

           begin
                          set @error=@@ERROR
                          if (@error<>0)
                          begin
                                         set @print_message=N'Error '+ RTRIM(cast(@error as nvarchar(10))) + ' - Message: '+ ERROR_MESSAGE();
                                         print(@print_message);
                          end
                          else
                                         print('No error is generated');
           end

           --Fetch log path

           if (@log_path ='' OR @log_path is null )
                          SELECT @log_path=cast(SERVERPROPERTY('InstanceDefaultLogPath') as nvarchar);
           if (@log_path ='' OR @log_path is null )
           begin
                          set @error=@@ERROR
                          if (@error<>0)
                          begin
                                         set @print_message=N'Error '+ RTRIM(cast(@error as nvarchar(10))) + ' - Message: '+ ERROR_MESSAGE();
                                         print(@print_message);
                          end
                          else
                                         print('No error is generated');
           end


            set @l_variable_data = concat('NAME =', '''',@DBName, '_DATA','''', ', FILENAME = ', '''', @data_path,'\',@DBName, '.mdf', '''', ', SIZE = ', @data_file_size, ', MAXSIZE = ', @data_file_maxsize,', FILEGROWTH = ',@data_file_filegrowth)
            set @l_variable_log  = concat('NAME =', '''',@DBName, '_LOG', '''', ', FILENAME = ', '''', @log_path, '\',@DBName, '.ldf', '''', ', SIZE = ', @log_file_size, ', MAXSIZE = ',  @log_file_maxsize,', FILEGROWTH = ',@log_file_filegrowth)

           set @complete_command = concat(' CREATE DATABASE ', @DBName , ' CONTAINMENT = NONE ON PRIMARY (', @l_variable_data, ')' , ' LOG ON (' , @l_variable_log , ')');


           exec(@complete_command);

end
"""

并且,下面是我处理 proc 的方式:

cursor.execute(Create_SQL_Proc_Statement)
cursor.execute('Exec db_creation_script  ?, ?, ?, ?, ?, ?, ?, ?, ?',(DB_Name,Data_Path,Data_File_Size,Data_File_Maxsize,Data_File_Filegrowth,Log_Path,Log_File_Size,Log_File_Maxsize,Log_File_Filegrowth))

我也尝试了以下方法:

cursor.execute('{ call db_creation_script  (?, ?, ?, ?, ?, ?, ?, ?, ?)}',(DB_Name,Data_Path,Data_File_Size,Data_File_Maxsize,Data_File_Filegrowth,Log_Path,Log_File_Size,Log_File_Maxsize,Log_File_Filegrowth))
cursor.execute('exec db_creation_script  {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}'.format(DB_Name,Data_Path,Data_File_Size,Data_File_Maxsize,Data_File_Filegrowth,Log_Path,Log_File_Size,Log_File_Maxsize,Log_File_Filegrowth))

但没有运气,我总是遇到以下异常:

 cursor.execute('exec db_creation_script  {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}'.format(DB_Name,Data_Path,Data_File_Size,Data_File_Maxsize,Data_File_Filegrowth,Log_Path,Log_File_Size,Log_File_Maxsize,Log_File_Filegrowth))
pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Incorrect syntax near ','. (102) (SQLExecDirectW)")

每次我运行上面的代码时,我都会收到不成功的消息,你能帮我了解一下我的脚本中的问题到底在哪里吗?如果有人可以让我知道是否有其他方法可以做到这一点,那就太好了。

注意:我正在使用 pyodbc python 模块来实现相同的效果

【问题讨论】:

  • 请删除 try ... except 块,并告诉我们运行 SQL 生产时引发的异常。
  • cursor.execute('exec #db_create ?, ?, ?, ?, ?, ?, ?',(DB_Name,Data_Path,Data_File_Size,Data_File_Maxsize,Log_Path,Log_File_Size,Log_File_Maxsize)) pyodbc.ProgrammingError : ('42000', "[42000] [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]',' 附近的语法不正确。(102) (SQLExecDirectW)")
  • edit您的问题添加所需的说明。
  • 现在您知道您的 SQL 定义中有语法错误。
  • 首先要做的是删除 try/except 块,这样您就可以从数据库中看到错误消息的全文,这应该有助于缩小范围。

标签: sql-server python-3.x pyodbc


【解决方案1】:

您需要确保该字符串对 SQLServer 有效

这里我做了必要的更改,存储过程是在我的实例上创建的,它是否有效是另一个问题:-)

我故意省略了 exec(complete command) 上面的 3 行,因为要输入很多引号 :-)

此脚本适用于 SSMS

       DECLARE @Create_SQL_Proc_Statement NVARCHAR(MAX);
       SELECT @Create_SQL_Proc_Statement = N'
       CREATE PROCEDURE db_creation_script
       @DBName nvarchar(50),
       @data_path nvarchar(50) ='''',
       @data_file_size nvarchar(50) = ''5000KB'',
       @data_file_maxsize nvarchar(50) = ''UNLIMITED'',
       @data_file_filegrowth nvarchar(50) = ''1024KB'',
       @log_path nvarchar(50) ='''',
       @log_file_size nvarchar(50) = ''5000KB'',
       @log_file_maxsize nvarchar(50) = ''1048576KB'',
       @log_file_filegrowth nvarchar(50) = ''1024KB''
       AS

       begin

       declare @l_variable_data as nvarchar(500);
       declare @l_variable_log as nvarchar(500);
       declare @complete_command as nvarchar(1000);
       declare @print_message as nvarchar(1000);
       declare @error as int;

       --Fetch data path

       if (@data_path ='''' OR @data_path is null )
                      SELECT @data_path=cast(SERVERPROPERTY(''InstanceDefaultDataPath'') as nvarchar);
       if (@data_path ='''' OR @data_path is null )

       begin
                      set @error=@@ERROR
                      if (@error<>0)
                      begin
                                     set @print_message=N''Error ''+ RTRIM(cast(@error as nvarchar(10))) + '' - Message: ''+ ERROR_MESSAGE();
                                     print(@print_message);
                      end
                      else
                                     print(''No error is generated'');
       end

       --Fetch log path

       if (@log_path ='''' OR @log_path is null )
                      SELECT @log_path=cast(SERVERPROPERTY(''InstanceDefaultLogPath'') as nvarchar);
       if (@log_path ='''' OR @log_path is null )
       begin
                      set @error=@@ERROR
                      if (@error<>0)
                      begin
                                     set @print_message=N''Error ''+ RTRIM(cast(@error as nvarchar(10))) + '' - Message: ''+ ERROR_MESSAGE();
                                     print(@print_message);
                      end
                      else
                                     print(''No error is generated'');
       end



       exec(@complete_command);

       end
       '           

       EXECUTE sp_executesql @Create_SQL_Proc_Statement 

【讨论】:

  • 我在执行存储过程时遇到了问题,所以我认为它不会有帮助。
  • 您是否有权访问 SSMS og 类似工具您需要确保创建的字符串 Create_SQL_Proc_Statement 对 SQL Server 有效您的问题来自字符串内需要引号这是前几行我会将其写入 SSMS 以使其有效(需要时请参见双引号: Create_SQL_Proc_Statement = N' CREATE PROCEDURE db_creation_script DBName nvarchar(50), data_path nvarchar(50) ='''', data_file_size nvarchar(50) = '' 5000KB'',
  • 我在想,为什么你需要一个存储过程来创建数据库?
  • 嗨@Peter,是的,这个答案和我的python脚本一起在SSMS中工作,非常感谢。现在,我的 python 脚本处理默认值时遇到了一个小问题。我的脚本是这样编码的,在调用这个 sql proc 时,我传入了所有参数,如下所示:cursor.execute('{ call db_creation_script_test (?, ?, ?, ?, ?, ?, ?, ?, ?)}',(A,B,C,D,E,F,G,H,I)) 现在,每当用户不输入参数时,我的默认值都应该被替换,而在我的情况下只有白色空格被替换为默认值 (''),这不允许我继续进行。
  • @alpha123 如果我正确理解 python 脚本,您总是将值传递给所有参数。尽管它可能是 NULL 值,但存储过程将其视为您想要的,而不是默认值。如果您想要默认值,则不得包含参数,或者,在您的情况下可能会更好:在存储过程中添加代码来评估传递的参数,如果传递的值为 NULL,则将其设置为默认值.
猜你喜欢
  • 2021-05-30
  • 2013-05-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-26
  • 1970-01-01
  • 2019-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多