bil*_*nkc 12 ssis sql-server-2012 sql-variant-property
我正在编写一个脚本来将环境从一台服务器移植到另一台服务器。我遇到了一个调用问题,catalog.create_environment_variable其中出现错误“输入值的数据类型与‘字符串’的数据类型不兼容。” 从过程“check_data_type_value”出来。
奇怪的是,如果我让 GUI 脚本输出变量,该查询将起作用
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
Run Code Online (Sandbox Code Playgroud)
但是,采用这种脚本方法是行不通的。我所做的工作表明此错误消息通常是通过使用 nvarchar 数据类型而不是 varchar 来解决的。然而,我的东西不是这样。
以下脚本的第 108 行。我的假设是sql_variant 有点奇怪,但我不知道那是什么。
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;
Run Code Online (Sandbox Code Playgroud)
bil*_*nkc 10
“我所做的工作表明此错误消息通常是通过使用 nvarchar 数据类型而不是 varchar 来解决的。但是,我的东西并非如此。” 或者是这样吗?
我对光标进行了两次更改。第一个在我的 CATCH 块中。我重新阅读了关于 sql_variant 数据类型的文章,然后阅读了sql_variant_property。我在我的 catch 块中添加了一个调用,希望看到nvarchar但你瞧,它报告varchar为我的 BaseType。
知道这一点并且我的所有源数据都是基于字符的,我欺骗并@local使用显式转换将变量添加到 nvarchar 并且它神奇地工作。
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;
Run Code Online (Sandbox Code Playgroud)
当我开始撰写调查结果摘要时,我发现了脱节。当我加载我的临时表 @EnvironmentVariables 时,我最初是直接从catalog.environment_variables.它那里获取的,为了使其更便携,我将这些值复制为 SELECT 语句。这是我搞砸的地方。当我重构这些值时,我将 Unicode 字符串变成了“mercan 字符串”。它们被作为非 unicode 写入 sql_variant 类型列,然后在它通过 proc 进行验证时爆炸。如果我正确地使用N修饰符(?)作为字符串的开头,它们将存储为 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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5503 次 |
| 最近记录: |