SSIS 2012 Tạo biến môi trường không thành công


12

Tôi đang làm một kịch bản để chuyển Môi trường từ máy chủ này sang máy chủ khác. Tôi đang gặp vấn đề khi gọi catalog.create_environment_variabletrong đó tôi gặp lỗi "Kiểu dữ liệu của giá trị đầu vào không tương thích với kiểu dữ liệu của 'Chuỗi'." sắp ra khỏi Proc "check_data_type_value."

Điều kỳ lạ là nếu tôi để tập lệnh GUI ra các biến, truy vấn đó sẽ hoạt động

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

Tuy nhiên, thực hiện phương pháp tiếp cận kịch bản này không hiệu quả. Các công việc tôi đã thực hiện chỉ ra thông báo lỗi này thường được giải quyết bằng cách sử dụng kiểu dữ liệu nvarchar thay vì varchar. Tuy nhiên, đó không phải là trường hợp của tôi.

Dòng 108 cho tập lệnh sau. Giả định của tôi là nó là thứ gì đó hấp dẫn với sql_variant nhưng tôi không biết thứ đó là gì.

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
Con trai. Tôi thất vọng.
swasheck

5
@swasheck Bạn có nhận ra niềm tự hào đã bị nuốt mất bao nhiêu trước khi tôi có thể nhấp vào nút Gửi không?
billinkc

Tôi không biến mất, bạn vừa cứu đêm của tôi. Freaking nVarChar
RThomas

Câu trả lời:


10

"Các công việc tôi đã thực hiện chỉ ra thông báo lỗi này thường được giải quyết bằng cách sử dụng kiểu dữ liệu nvarchar thay vì varchar. Tuy nhiên, đó không phải là trường hợp của công cụ của tôi." Hay nó là trường hợp?

Tôi đã thực hiện hai thay đổi cho con trỏ của tôi. Đầu tiên là trong khối CATCH của tôi. Tôi đọc lại bài viết về kiểu dữ liệu sql_variant và theo sau với sql_variant_property . Tôi đã thêm một cuộc gọi đến đó trong khối bắt của mình, hy vọng sẽ thấy nvarcharnhưng lo và kìa, nó báo cáo lại varcharlà BaseType của tôi.

Biết rằng và tất cả dữ liệu nguồn của tôi là dựa trên ký tự, tôi đã lừa và thêm @local biến với một diễn viên rõ ràng vào nvarchar và nó hoạt động một cách kỳ diệu.

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;

Phân tích nguyên nhân gốc rễ

Khi tôi bắt đầu viết một bản tóm tắt các phát hiện, tôi phát hiện ra sự ngắt kết nối. Khi tôi đang tải bảng tạm thời của mình, @En MôiVariabled, ban đầu tôi đã lấy nguồn đó trực tiếp từ catalog.environment_variables.Để làm cho nó dễ mang theo hơn, tôi đã sao chép các giá trị ra dưới dạng các câu lệnh CHỌN. Đây là nơi tôi làm hỏng việc. Khi tôi hoàn nguyên các giá trị đó, tôi đã tạo các chuỗi Unicode thành 'chuỗi mercan. Chúng được ghi vào cột kiểu sql_variant dưới dạng không unicode, sau đó nó sẽ nổ tung khi nó được thông qua trong Proc để xác nhận. Nếu tôi mở đầu chính xác các chuỗi của mình bằng công cụ Nsửa đổi (?) Thì chúng được lưu trữ dưới dạng nvarchar.

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)

Tôi đã sử dụng một biến thể của thefirstsql.com/2013/05/28/ này để tạo tập lệnh của tôi /. Nếu tôi hiểu chính xác, tôi cần đảm bảo tất cả các chuỗi ký tự của tôi bắt đầu bằng Nnhưng tôi vẫn gặp vấn đề này. Trong thực tế, tôi nhận được khiếu nại về boolean và datetime nhưng không có tham số nào của tôi sử dụng các kiểu dữ liệu hicky. Bạn có cái nhìn sâu sắc nào không?
Nick.McDilyn 27/11/18

1

Chỉ cần thêm vào @billinkc câu trả lời tuyệt vời (chắc chắn bạn biết bạn sẽ là người trả lời câu hỏi này !!) và làm giàu kiến ​​thức xung quanh điều này ....

Đây là một số mã mẫu, được tạo tự động từ đây https://thefirstsql.com/2013/05/28/ssis-2012-easily-copy-en môi-biến-to- new-subvers-or-new-envirments / sẽ ném lỗi :

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'

Cụ thể là lỗi

Msg 27147, Cấp 16, Trạng thái 1, Quy trình nội bộ.check_data_type_value, Dòng 22 [Batch Start Line 0] Kiểu dữ liệu của giá trị đầu vào không tương thích với kiểu dữ liệu của 'Int64'.

Tôi cũng có các lỗi khác cho datetime và boolean

Vì vậy, không cần phải hiểu rõ vấn đề, về cơ bản, giải pháp là sử dụng một kiểu dữ liệu cụ thể thay vì sql_variantkhi truyền một giá trị vào @valuetham số.

Đối với Int64 và Boolean, bạn chỉ có thể mã cứng giá trị nhưng đối với datetimebạn phải khai báo trước một biến loại datetimevà sử dụng nó - bạn không thể chuyển vào một chuỗi ngày theo nghĩa đen

Đây là lần đầu tiên tôi thấy một tham số trong một thủ tục được lưu trữ dường như chấp nhận nhiều loại dữ liệu.

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'

Làm cho ý nghĩa tuyệt vời trở nên rõ ràng thay vì sử dụng một kích cỡ phù hợp với tất cả từ SQL-Server-2000
billinkc
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.