Программное сохранение результатов запроса в файл SQL - PullRequest
0 голосов
/ 09 июля 2020

У меня есть хранимая процедура, которая генерирует операторы Insert и Update. Поэтому я хочу, чтобы pro c сохранял результаты в файл .sql.

ALTER PROCEDURE [dbo].[Sp_GenerateScripts]
@FilePath NVARCHAR(MAX) = ''
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @Message NVARCHAR(155)
    DECLARE @Query NVARCHAR(MAX) = ''
    DECLARE @GenerateInserts NVARCHAR(MAX) = ''
    DECLARE @GenerateUpdates NVARCHAR(MAX) = ''
    IF OBJECT_ID('tempdb..##DataImport') IS NOT NULL DROP TABLE ##DataImport

    CREATE TABLE ##DataImport
    (
        [LongTextId] varchar(150) NULL,
        [Code] [nvarchar](255) NULL,
        [Product] [nvarchar](max) NULL,
        [Category] [nvarchar](max) NULL,
        [Subsegment] [nvarchar](max) NULL,
        [DescriptionText] [nvarchar](max) NULL,
        [eDate] [nvarchar](max) NULL,
        [ExpirationDate] [nvarchar](max) NULL,
        [UpdatedOn] [nvarchar](max) NULL
    )

    --BULK INSERT ##DataImport from 'C:\CSV Files\file.csv' WITH 
    SET @Query = 'BULK INSERT ##DataImport FROM ''' + @FilePath + ''' WITH 
    (
        FIELDTERMINATOR = ''|'',
        FIRSTROW = 2        
    )';

    exec sp_executesql @Query;

    /*CSV Data Cleansing*/
    UPDATE ##DataImport 
    set [LongTextId] = NEWID()
    WHERE LEN([LongTextId]) != 36

    UPDATE ##DataImport
    SET UpdatedOn = SUBSTRING(UpdatedOn, 1, CHARINDEX('|', UpdatedOn) - 1)

    DELETE ##DataImport WHERE LongTextId IS NULL;   

    SELECT 'BEGIN TRAN'
    UNION ALL
    SELECT 
        --*,
        'UPDATE [dbo].[Table1] SET' 
    + '  [Code] = ''' + [Code]  + ''''
    + ', [Product] = ''' + [Product]  + ''''
    + ', [Category] = ''' + [Category]  + ''''
    + ', [Subsegment] = ''' + [Subsegment]  + ''''
    + ', [DescriptionText] = ''' + REPLACE([DescriptionText], '''', '''''') + ''''

    + ', [Date] = ''' + [EffectiveDate]  + ''''
    + ', [ExpirationDate] = ''' + [ExpirationDate]  + ''''
    + ', [UpdatedOn] = ''' + [UpdatedOn]  + ''''
    + ' WHERE [LongTextId] = ''' + [LongTextId] + ''';' + CHAR(10) 
    from ##DataImport src 
    WHERE EXISTS 
            (
                SELECT 1 
                FROM 
                    [dbo].TABLE1 AS dest
                WHERE 
                    dest.[LongTextId] = src.[LongTextId]
            )
    UNION ALL 
    SELECT 'INSERT INTO [dbo].[TABLE1] ([Subsegment], [DescriptionText], [LongTextId], [Code], [Date], [ExpirationDate], [Product], [Category], [UpdatedOn]) VALUES (' 
    + '''' + [CustomerSubsegment] + ''', '
    + '''' + REPLACE([DescriptionText], '''', '''''') + ''', '
    + '''' + [LongTextId] + ''', '
    + '''' + [Code] + ''', '
    + '''' + [Date] + ''', '
    + '''' + [Expirationdate] + ''', '
    + '''' + [Product] + ''', '
    + '''' + [Category] + ''', '
    + '''' + [UpdatedOn] + ''');'
    
    from ##DataImport src 
    WHERE NOT EXISTS 
            (
                SELECT 1 
                FROM 
                    [dbo].[TABLE1] AS dest
                WHERE 
                    dest.[LongTextId] = src.[LongTextId]
            )
    UNION ALL
    SELECT 'COMMIT TRAN'
END

Этот pro c отлично работает, и я его так называю:

EXEC [dbo].[Sp_GenerateScripts] 'C:\CSV Files\Text_3.csv'

Что мне нужно сделать, так это записать результаты сохраненного pro c в файл .sql где-нибудь в общую папку или локальную папку, не имеет значения. Итак, я попытался сделать это в PowerShell, как это

sqlcmd -S SERVER-PC -d DB1 -E -Q "EXEC [dbo].[Sp_GenerateScripts] 'C:\CSV Files\Text_3.csv'" -o "C:\Export.sql"

В PowerShell он работает, но я не хочу использовать этот метод. Есть ли способ сделать это в T- SQL? Если да, как я могу изменить сохраненный pro c для этого?

1 Ответ

0 голосов
/ 09 июля 2020

Вы можете выполнить ту же команду sqlcmd из T SQL, используя xp_Cmdshell. Но использование xp_cmdshell сопряжено со своими рисками, поскольку может запускать системные команды. Поэтому следует проявлять осторожность, прежде чем включать эту опцию с помощью sp_configure. Кроме того, если вы планируете использовать это, лучше выполнять с использованием наименее привилегированного пользовательского контекста. Вы можете настроить учетную запись прокси для работы с xp_cmdshell, используя sp_xp_cmdshell_proxy_account.

Подробнее о xp_cmdshell

EXEC xp_cmdshell 'sqlcmd -S SERVER-PC -d DB1 -E 
-Q "EXEC [dbo].[Sp_GenerateScripts] ''C:\CSV Files\Text_3.csv''" -o "C:\Export.sql"'

Если xp_cmdshell не рекомендуется в качестве меры безопасности, в качестве альтернативы , вы можете иметь хранимую процедуру CLR, специально для этой цели. Опять же, для этого требуется включить CLR, используя sp_configure.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...