AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 46556
Accepted
billinkc
billinkc
Asked: 2013-07-18 13:59:09 +0800 CST2013-07-18 13:59:09 +0800 CST 2013-07-18 13:59:09 +0800 CST

SSIS 2012 创建环境变量失败

  • 772

我正在编写一个脚本来将环境从一台服务器移植到另一台服务器。我遇到了一个调用问题,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

但是,采用这种脚本方法是行不通的。我所做的工作表明此错误消息通常通过使用 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;
ssis sql-server-2012
  • 2 2 个回答
  • 6070 Views

2 个回答

  • Voted
  1. Best Answer
    billinkc
    2013-07-18T19:33:54+08:002013-07-18T19:33:54+08:00

    “我所做的工作表明此错误消息通常可以通过使用 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;
    

    根本原因分析

    当我开始撰写调查结果摘要时,我发现了这种脱节。当我加载我的临时表 @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)
    
    • 11
  2. Nick.McDermaid
    2018-11-27T18:00:05+08:002018-11-27T18:00:05+08:00

    只是为了添加到@billinkc 出色的答案(当然你知道你会是回答这个问题的人!!)并丰富这方面的知识......

    这是一些示例代码,从这里自动生成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'
    

    具体的错误是

    消息 27147,级别 16,状态 1,过程 internal.check_data_type_value,第 22 行 [批处理开始行 0] 输入值的数据类型与“Int64”的数据类型不兼容。

    我还有其他日期时间和布尔值错误

    因此,在没有深入理解问题的情况下,解决方案基本上是使用特定的数据类型,而不是sql_variant在将值传递给@value参数时。

    对于 Int64 和 Boolean,您可以对值进行硬编码,但datetime您必须预先声明一个类型的变量datetime并使用它 - 您不能只传入字符串日期文字

    这是我第一次看到存储过程中的参数显然可以接受多种数据类型。

    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'
    
    • 1

相关问题

  • 在 Microsoft BI 中查找改进材料

  • 约束 SSIS 执行进程任务的最简单方法

  • 为什么 Denali 序列应该比标识列表现更好?

  • SQL Server 不应该支持范围吗?

  • 什么是 SQL Server“德纳利”?什么是新的?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    授予用户对所有表的访问权限

    • 5 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve