Powershell: запуск сохраненной процедуры с динамическим sql не работает

#sql #powershell

#sql #powershell

Вопрос:

Я использую приведенный ниже код Powershell для вызова SP, который выполнит некоторую работу. SP имеет динамический sql и находится ниже. Файл, из которого я извлекаю, находится там и содержит данные. На самом деле, когда я запускаю процедуру напрямую из SQL, она работает нормально, поэтому PS почему-то не нравится этот вызов. Кто-нибудь видит здесь что-нибудь неправильное? Единственное, что я могу подумать, это то, что динамический SQL не будет запускаться через PS …??

 $SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=myserver;Database=Stats;Integrated Security=True"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = "spCSVToSQL 'H:StatsStats.csv'"
$SqlCmd.Connection = $SqlConnection
$SqlConnection.Open
$sqlCmd.ExecuteNonQuery
$SqlConnection.Close
===================================================================================
ALTER procedure [dbo].[spCSVToSQL] @filePath varchar(250)
as
Begin

declare @sql varchar(2500) =
'CREATE TABLE ##Stats
(
[StatDate] [varchar](50) NULL,
[Server] [varchar](50) NULL,
[DriveLetter] [varchar](50) NULL,
[Label] [varchar](50) NULL,
[Capacity] [varchar](50) NULL,
[FreeSpace] [varchar](50) NULL,
[PercFree] [varchar](50) NULL,
[PercFrag] [varchar](50) NULL
)
BULK INSERT ##Stats
 FROM '''   @filePath   '''
 WITH (FIELDTERMINATOR = '','', FIRSTROW = 2, ROWTERMINATOR = ''n'') 
 INSERT INTO [cStats].[dbo].[StatInfo]
 SELECT Convert(VARCHAR, RTRIM(LTRIM(REPLACE([StatDate], ''"'',''''))), 113)
      ,CONVERT(VARCHAR, RTRIM(LTRIM(REPLACE([Server], ''"'',''''))))
      ,CONVERT(VARCHAR, RTRIM(LTRIM(REPLACE([DriveLetter], ''"'',''''))))
      ,CONVERT(VARCHAR, RTRIM(LTRIM(REPLACE([Label], ''"'',''''))))
      ,CONVERT(BIGINT, RTRIM(LTRIM(REPLACE([Capacity], ''"'',''''))))
      ,CONVERT(BIGINT, RTRIM(LTRIM(REPLACE([FreeSpace], ''"'',''''))))
      ,CONVERT(INT, RTRIM(LTRIM(REPLACE([PercFree], ''"'',''''))))
      ,CONVERT(INT, RTRIM(LTRIM(REPLACE([PercFrag], ''"'',''''))))
      FROM ##Stats

      drop table ##Stats'      
   exec(@sql)      
  End
  

Комментарии:

1. «PS почему-то не нравится этот вызов» — не совсем подходящее описание того, что происходит. Не могли бы вы, пожалуйста, точно описать, какое поведение вы наблюдаете? Вы видите какую-либо ошибку? Если да, то каков текст сообщения об ошибке?

Ответ №1:

Из того, что вы опубликовали, у вас отсутствуют скобки в последних трех вызовах:

 $SqlConnection.Open()
$sqlCmd.ExecuteNonQuery()
$SqlConnection.Close()
  

Я протестировал ваш код здесь, и он работает нормально. Вот что я сделал.

  • Я создал таблицу StatInfo в тестовой базе данных со схемой, которая точно соответствует ##Stats. Я знаю, что для вас это не так, но этого достаточно, чтобы доказать, что это работает
  • Я создаю процедуру sp следующим образом:

     CREATE procedure [dbo].[spCSVToSQL] @filePath varchar(250)
    as
    Begin
    
    declare @sql varchar(2500) =
    'CREATE TABLE ##Stats
    (
    [StatDate] [varchar](50) NULL,
    [Server] [varchar](50) NULL,
    [DriveLetter] [varchar](50) NULL,
    [Label] [varchar](50) NULL,
    [Capacity] [varchar](50) NULL,
    [FreeSpace] [varchar](50) NULL,
    [PercFree] [varchar](50) NULL,
    [PercFrag] [varchar](50) NULL
    )
    BULK INSERT ##Stats
     FROM '''   @filePath   '''
     WITH (FIELDTERMINATOR = '','', FIRSTROW = 2, ROWTERMINATOR = ''n'') 
     INSERT INTO [Test].[dbo].[StatInfo]
     SELECT Convert(VARCHAR, RTRIM(LTRIM(REPLACE([StatDate], ''"'',''''))), 113)
          ,CONVERT(VARCHAR, RTRIM(LTRIM(REPLACE([Server], ''"'',''''))))
          ,CONVERT(VARCHAR, RTRIM(LTRIM(REPLACE([DriveLetter], ''"'',''''))))
          ,CONVERT(VARCHAR, RTRIM(LTRIM(REPLACE([Label], ''"'',''''))))
          ,CONVERT(BIGINT, RTRIM(LTRIM(REPLACE([Capacity], ''"'',''''))))
          ,CONVERT(BIGINT, RTRIM(LTRIM(REPLACE([FreeSpace], ''"'',''''))))
          ,CONVERT(INT, RTRIM(LTRIM(REPLACE([PercFree], ''"'',''''))))
          ,CONVERT(INT, RTRIM(LTRIM(REPLACE([PercFrag], ''"'',''''))))
          FROM ##Stats
    
          drop table ##Stats'      
       exec(@sql)      
      End
    
    GO
      
  • Я создаю файл C:Stats.csv это выглядит следующим образом:

     1,2,3,4,5,6,7,8
    1,2,3,4,5,6,7,8
    1,2,3,4,5,6,7,8
    1,2,3,4,5,6,7,8
    1,2,3,4,5,6,7,8
    1,2,3,4,5,6,7,8
    1,2,3,4,5,6,7,8
    1,2,3,4,5,6,7,8
    1,2,3,4,5,6,7,8
    1,2,3,4,5,6,7,8
      
  • Я запустил следующее в Powershell:

     $SqlConnection = New-Object System.Data.SqlClient.SqlConnection
    $SqlConnection.ConnectionString = "Server=(local);Database=Test;Integrated Security=True"
    $SqlCmd = New-Object System.Data.SqlClient.SqlCommand
    $SqlCmd.CommandText = "spCSVToSQL 'C:Stats.csv'"
    $SqlCmd.Connection = $SqlConnection
    $SqlConnection.Open()
    $sqlCmd.ExecuteNonQuery()
    $SqlConnection.Close()
      
  • После этого я проверил содержимое Test.dbo.StatInfo и подтвердил, что дата с C:Stats.csv там ничего не отображается.

Обратите внимание, что во избежание столкновения имен, возможно, было бы лучше назвать временную таблицу #Stats , а не ##Stats . Разница в том, что ##Stats она видна вне соединения, которое ее создает, а #Stats нет.

Комментарии:

1. Это просто сумасшедший! 🙂 У меня были скобки, и это выдавало ошибки. Забавно, что она не выдаст ошибок, если вы не используете, а они необходимы. Я верну их обратно и посмотрю, что произойдет.

Ответ №2:

Следует отметить пару моментов: open и close — это методы, поэтому используйте parenthis: т.е.

$SqlConnection.Открыть()

включите инструкцию «exec» в текст команды: «exec spCSVToSQL ‘H:StatsStats.csv ‘»

Ответ №3:

У меня никогда не возникало проблем с запуском любого вида sql через Powershell. Что происходит, когда «PS почему-то не нравится этот вызов»? Вы получаете сообщение об ошибке?