SSIS 2012 Ortam değişkeni oluşturma başarısız


12

Bir ortam bir sunucudan diğerine taşımak için bir komut dosyası çalışıyorum. catalog.create_environment_variable"Girdi değerinin veri türü 'Dize' veri türü ile uyumlu değil" hatası alıyorum bir sorun çağrı çalıştırıyorum . "check_data_type_value" işleminden çıkıyor.

Garip olan şey, GUI betiğinin değişkenleri dışarıda bırakması durumunda, bu sorgunun işe yarayacağıdır.

DECLARE @var sql_variant = N'\\myserver\ssisdata'
EXEC [catalog].[create_environment_variable]
    @variable_name = N'FolderBase'
,   @sensitive = False
,   @description = N''
,   @environment_name = N'Development'
,   @folder_name = N'POC'
,   @value = @var
,   @data_type = N'String'
GO

Ancak, bu komut dosyası yaklaşımını kullanmak işe yaramıyor. Yaptığım ayak işlemi, bu hata mesajının genellikle varchar yerine nvarchar veri türü kullanılarak çözüldüğünü gösteriyor. Ancak, işlerim için durum böyle değil.

Aşağıdaki komut dosyası için 108. satır. Benim varsayım, sql_variant ile sakat bir şey olduğunu, ancak bu şeyin ne olduğu hakkında hiçbir fikrim yok .

USE SSISDB;
GO

DECLARE
    @folder_id bigint
,   @folder_name nvarchar(128) = N'POC'
,   @environment_name nvarchar(128) = N'Development'
,   @environment_description nvarchar(1024)
,   @reference_id bigint
,   @variable_name nvarchar(128)
,   @data_type nvarchar(128)
,   @sensitive bit
,   @value sql_variant
,   @description nvarchar(1024);

IF NOT EXISTS
(
    SELECT * FROM catalog.folders AS F WHERE F.name = @folder_name
)
BEGIN
    EXECUTE catalog.create_folder
        @folder_name = @folder_name
    ,   @folder_id = @folder_id OUTPUT;

    PRINT CONCAT('Folder "', @folder_name, '" has been created with a folder_id of ', @folder_id)
END

IF NOT EXISTS
(
    SELECT * FROM catalog.environments AS E WHERE E.name = @environment_name 
    AND E.folder_id = (SELECT F.folder_id FROM catalog.folders AS F WHERE F.name = @folder_name)
)
BEGIN
    PRINT CONCAT('Creating environment ',  @environment_name);

    EXECUTE catalog.create_environment
        @folder_name = @folder_name
    ,   @environment_name = @environment_name
    ,   @environment_description = @environment_description;
END

DECLARE
    @EnvironmentVariables TABLE
(
    folder_name nvarchar(128)
,   environment_name nvarchar(128)
,   variable_name nvarchar(128)
,   description nvarchar(1024)
,   data_type nvarchar(128)
,   sensitive bit
,   value sql_variant
);

INSERT INTO
    @EnvironmentVariables
SELECT
    E.folder_name
,   E.environment_name
,   S.name
,   S.description
,   S.type
,   S.sensitive
,   S.value
FROM
(
    SELECT 'FolderBase','Root for ssis processing','String',CAST(0 AS bit),'\\myserver\ssisdata'
    UNION ALL SELECT 'AuditConnectionString','Conn to audit db','String',CAST(0 AS bit),'Data Source=SQLETL01;Initial Catalog=Audit;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;'
) AS S (name, description, type, sensitive, value)
CROSS APPLY
(
    SELECT
        E.name AS environment_name
    ,   F.name AS folder_name
    FROM
        catalog.folders AS F
        INNER JOIN
            catalog.environments AS E
            ON E.folder_id = F.folder_id
    WHERE
        F.name = @folder_name
        AND E.name = @environment_name
) E;


DECLARE Csr CURSOR FORWARD_ONLY STATIC FOR
SELECT
    EV.variable_name
,   EV.description
,   EV.data_type
,   EV.sensitive
,   EV.value
FROM
    @Environmentvariables AS EV;

OPEN Csr;
FETCH NEXT FROM Csr INTO
    @variable_name
,   @description
,   @data_type
,   @sensitive
,   @value;

WHILE @@FETCH_STATUS = 0
BEGIN

    BEGIN TRY
            -- THERE BE MONSTERS AHEAD
        -- The data type of the input value is not compatible with the data type of the 'String'. 
        EXECUTE catalog.create_environment_variable
            @variable_name = @variable_name
        ,   @sensitive = @sensitive
        ,   @description = @description
        ,   @environment_name = @environment_name
        ,   @folder_name = @folder_name
        ,   @value = @value
        ,   @data_type = @data_type
    END TRY
    BEGIN CATCH
        SELECT 
            @folder_name        AS folder_name
        ,   @environment_name   AS environment_name
        ,   @variable_name      AS variable_name
        ,   @data_type          AS data_type
        ,   @sensitive          AS sensitive
        ,   @value              AS value
        ,   @description        AS description
        ,   ERROR_NUMBER()AS error_number --returns the number of the error.
        ,   ERROR_SEVERITY() AS error_severity --returns the severity.
        ,   ERROR_STATE()AS error_state  --returns the error state number.
        ,   ERROR_PROCEDURE() AS error_procedure --returns the name of the stored procedure or trigger where the error occurred.
        ,   ERROR_LINE() AS error_line --returns the line number inside the routine that caused the error.
        ,   ERROR_MESSAGE() AS error_message; --returns the complete text of the error message. The text includes the values supplied for any substitutable parameters, such as lengths, object names, or times.

    END CATCH  

    FETCH NEXT FROM Csr INTO
        @variable_name
    ,   @description
    ,   @data_type
    ,   @sensitive
    ,   @value;
END

CLOSE Csr;
DEALLOCATE Csr;

7
Oğul. Hayal kırıklığına uğratıyorum.
swasheck

5
@swasheck Gönder düğmesini tıklayabilmem için ne kadar gururun yutulduğunu anlıyor musunuz?
billinkc

Hayal kırıklığına uğramadım, sadece gecemi kurtardın. Kahrolası Nvarchar
RThomas

Yanıtlar:


10

"Yaptığım ayak işi, bu hata mesajının genellikle varchar yerine nvarchar veri türü kullanılarak çözüldüğünü gösteriyor. Ancak, işlerim için durum böyle değil." Yoksa durum böyle mi?

İmlecimde iki değişiklik yaptım. Birincisi CATCH bloğumda. Ben Sql_variant veri türüne makaleyi tekrar okunur ve takip sql_variant_property . Yakalama bloğuma bir çağrı ekledim, görmeyi bekliyorum nvarcharama lo ve işte, varcharBaseType'ım olarak rapor veriyor .

Bunu ve tüm kaynak verilerimin karakter tabanlı olduğunu bilerek, @localdeğişkeni nvarchar'a açık bir kadro ile ekledim ve sihirli bir şekilde çalışıyor.

WHILE @@FETCH_STATUS = 0
BEGIN

    BEGIN TRY
        -- THERE BE MONSTERS AHEAD
        -- The data type of the input value is not compatible with the data type of the 'String'. 
        DECLARE
            @local nvarchar(4000) = CONVERT(nvarchar(4000), @value);
        EXECUTE catalog.create_environment_variable
            @variable_name = @variable_name
        ,   @sensitive = @sensitive
        ,   @description = @description
        ,   @environment_name = @environment_name
        ,   @folder_name = @folder_name
        ,   @value = @local
        ,   @data_type = @data_type
    END TRY
    BEGIN CATCH
        SELECT 
            @folder_name        AS folder_name
        ,   @environment_name   AS environment_name
        ,   @variable_name      AS variable_name
        ,   @data_type          AS data_type
        ,   @sensitive          AS sensitive
        ,   @value              AS value
        ,   SQL_VARIANT_PROPERTY(@value, 'BaseType') As BaseType
        ,   @description        AS description
        ,   ERROR_NUMBER()AS error_number --returns the number of the error.
        ,   ERROR_SEVERITY() AS error_severity --returns the severity.
        ,   ERROR_STATE()AS error_state  --returns the error state number.
        ,   ERROR_PROCEDURE() AS error_procedure --returns the name of the stored procedure or trigger where the error occurred.
        ,   ERROR_LINE() AS error_line --returns the line number inside the routine that caused the error.
        ,   ERROR_MESSAGE() AS error_message; --returns the complete text of the error message. The text includes the values supplied for any substitutable parameters, such as lengths, object names, or times.

    END CATCH  

    FETCH NEXT FROM Csr INTO
        @variable_name
    ,   @description
    ,   @data_type
    ,   @sensitive
    ,   @value;
END

CLOSE Csr;
DEALLOCATE Csr;

Sorun kaynağı çözümlemesi

Bulguların bir özetini yazmaya başladığımda bağlantıyı keşfettim. Geçici tablomu, @EnvironmentVariables yüklerken, ben aslında doğrudan catalog.environment_variables.daha taşınabilir hale getirmek için, değerleri SELECT deyimleri olarak kopyaladı kaynak. Burası berbat ettiğim yer. Bu değerleri yeniden oluşturduğumda, Unicode dizelerini mercan dizelerine dönüştürdüm. Sql_variant tip sütununa unicode olmayan olarak yazıldılar ve bunlar daha sonra doğrulama için proc'ye geçtiğinde patladı. Dizelerimi Ndeğiştirici (?) İle önceden önseler, nvarchar olarak saklanırlar.

FROM
(
    SELECT 'FolderBase','Root for ssis processing','String',CAST(0 AS bit),N'\\myserver\ssisdata'
    UNION ALL SELECT 'AuditConnectionString','Conn to audit db','String',CAST(0 AS bit),N'Data Source=SQLETL01;Initial Catalog=Audit;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;'
) AS S (name, description, type, sensitive, value)

Senaryomu oluşturmak için bu thefirstsql.com/2013/05/28/… bir varyantı kullandım . Doğru anlıyorsam, tüm dize değişmezleri ile başlamak emin olmak gerekir Nama yine de bu sorunu var. Aslında boolean ve datetime hakkında şikayetler alıyorum ama parametrelerimin hiçbiri htese veri türlerini kullanmıyor. Herhangi bir fikrin var mı?
Nick.McDermaid

1

Sadece @billinkc mükemmel cevap eklemek için (kesinlikle bu soruyu cevaplamak için sen olacağını biliyordum !!) ve bu konuda bilgi zenginleştirmek ....

İşte buradan otomatik olarak oluşturulan bazı hatalar https://thefirstsql.com/2013/05/28/ssis-2012-easily-copy-environment-variables-to-new-servers-or-new-environments/ :

DECLARE @var sql_variant

SET @var = '2'
IF NOT EXISTS (
    SELECT 1 FROM [catalog].[environment_variables] 
    WHERE environment_id = @environment_id 
    AND name = N'MyVariable')
EXEC [catalog].[create_environment_variable] 
    @variable_name=N'SystemCd', 
    @sensitive=0, @description=N'', 
    @environment_name=@env_name, 
    @folder_name=@folder, 
    @value=@var, 
    @data_type=N'Int64'

Özellikle hata

Msg 27147, Seviye 16, Durum 1, Prosedür internal.check_data_type_value, Satır 22 [Toplu Başlangıç ​​Satırı 0] Giriş değerinin veri tipi, 'Int64' veri tipiyle uyumlu değil.

Datetime ve boolean için başka hatalar da vardı

Bu nedenle, sorunu anlamak için büyük çaba sarf etmeden, çözüm temel olarak parametreye sql_variantbir değer iletmek yerine belirli bir veri türü kullanmaktı @value.

Int64 ve Boolean için sadece sert kod değerini can fakat için datetimesize sahip türde bir değişken bildirmek öncesi datetimeve kullanmak - Eğer sadece bir dize tarih sabit içinde geçemez

Saklı bir yordamda ilk defa bir parametre gördüm görünüşte çeşitli veri türlerini kabul ediyorum.

DECLARE @var sql_variant
DECLARE @var_int int

SET @var = '2'
IF NOT EXISTS (
    SELECT 1 FROM [catalog].[environment_variables] 
    WHERE environment_id = @environment_id 
    AND name = N'MyVariable')
EXEC [catalog].[create_environment_variable] 
    @variable_name=N'SystemCd', 
    @sensitive=0, @description=N'', 
    @environment_name=@env_name, 
    @folder_name=@folder, 
    @value=@var_int, 
    @data_type=N'Int64'

SQL-Server-2000'den tek boyutlu bir yerine
sığdırmak
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.