【问题标题】:Getting error for HierarchyId while fetching the data from another server and inserting it into my server c#从另一台服务器获取数据并将其插入到我的服务器 c# 时出现 HierarchyId 错误
【发布时间】:2019-09-04 05:51:54
【问题描述】:

错误是

不支持“MemberHId”列的类型。类型是'SqlHierarchyId'。

在两个服务器中,数据类型都是相同的“HierarchyId”。

我只是在使用 ADO.Net。

程序集是 Microsoft.SqlServer.ManagedDTS 版本 - 13.0.0.0 我们正在使用 Azure Sql。

尝试使用不同版本的 sql 程序集

 DataTable dt = new DataTable();
 
 dt.Columns.Add("Code", typeof(string));
 dt.Columns.Add("Description", typeof(string));
 dt.Columns.Add("NodeId", typeof(int));
 dt.Columns.Add("MemberHId", typeof(SqlHierarchyId));
 dt.Columns.Add("Level", typeof(int));
                   
//Getting the data from serverAPI which is returning the data in the columns without null records.
 dt=apicall();

 SqlParameter returnParameter = cmd.Parameters.Add("RetVal", SqlDbType.Int);
 returnParameter.Direction = ParameterDirection.ReturnValue;
                
 cmd.CommandType = CommandType.StoredProcedure;
 cmd.CommandText = spName;
 cmd.Parameters.AddWithValue("@MemberH", dt);

 cmd.CommandTimeout = 0;
 cmd.Connection.Open();
 cmd.ExecuteNonQuery();// Its failing here

我的 Sp 由表类型参数 @MemberHType 组成,并且该过程返回具有这些列的行:

    Name        | Type
    ------------+----------
    Code        | varchar
    Description | varchar
    NodeID      | smallint
    MemberHId   | hierarchyid
    Level       | smallint

这是程序:

    alter PROCEDURE [dbo].[InsertHierarchyData]  
    (  
      @MemberHType MemberH READONLY  
    )  
    AS  
    
    truncate table test
    BEGIN TRY   
     
       insert into test values ('start select')
      
     --create table test (errormessage varchar(1000))
    
     IF EXISTS (SELECT TOP 1 1 FROM @MemberHType)  
     BEGIN  
    
     insert into test values ('Inside first Insert start')
      INSERT INTO HierarchyStaging  
      (  
       Code  
       ,[Description]  
       ,NodeID  
       ,MemberhHId  
       ,[Level]  
      )  
      SELECT    
        Code  
        ,[Description]  
        ,NodeId  
        ,MemberhHId  
        ,[Level]  
      FROM @MemberHType  
      insert into test values ('Inside first Insert end')
     END  
     END TRY    
    BEGIN CATCH    
     SELECT   @comment = ERROR_MESSAGE()    
       ,@Status = 'Error'    
     SET   @comment = CONVERT(NVARCHAR(3000),@Comment) + ' Error Severity: ' + CAST(ERROR_SEVERITY() AS varchar(25)) + ' Error state: 30'    
     GOTO ErrorHandler    
    END CATCH    
    The Column in c# is SqlHierarchyId.

堆栈跟踪:

at System.Data.SqlClient.TdsParser.TdsExecuteRPC(SqlCommand cmd, _SqlRPC[] rpcArray, Int32 timeout, Boolean inSchema, SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj, Boolean isCommandProc, Boolean sync, TaskCompletionSource`1 completion, Int32 startRpc, Int32 startParam)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()

【问题讨论】:

  • 你能添加你的存储过程吗?
  • Azure SQL 支持hierarchyid:docs.microsoft.com/en-us/sql/t-sql/data-types/… - 你真的在使用Azure SQL 数据仓库吗?
  • 另外,我理解在互联网上发帖时需要隐藏敏感信息,但请不要混淆您的数据,以至于用简单的类型替换整个复杂类型的列表/数组/表sproc 的“@table”参数中的“数据”字符串。显示带有虚拟数据的实际示例对象
  • 这个问题不能仅仅根据它所包含的信息来回答。请记住,我们没有人能读懂你的想法。如果您想回答您的问题,请创建一个适当的minimal reproducible example
  • 好的,将编辑它

标签: c# ssis ado.net hierarchical-data azure-sql-server


【解决方案1】:

如果我对文档的理解正确,您不能将SqlHierarchyId 用作DataColumn 的数据类型。

它没有出现在System.Data.SqlTypes Namespace 中,也没有出现在SQL Server Data Type Mappings 表中,这意味着在 SQL Server 的 HierarchyId 和 .网络框架。 (当然,已知 SQL Server 中存在未记录的功能,但我不建议依赖它)。

但是,您可以做的是,当您将 HierarchyId 读入您的 c# 应用程序(内部调用 ToString() 方法)时,使用 T-SQL 中的简单 cast 将其转换为 nvarchar

CAST(MemberhHId  AS nvarchar(4000)) as MemberHId

并在插入数据时使用cast 将其转换回来(内部调用Parse() 方法):

CAST(MemberHId AS hierarchyid) 

【讨论】:

  • 嘿 Zohar,SqlHierarchyId 存在于 Microsoft.SqlServer.Types.dll 中,并且在分配 sp 时出现错误,即将参数从 C# 传递给 sp。
  • 是的,它存在是因为它是 SQL Server 中的 CLR 类型。这并不意味着它可以用作使用 ADO.Net 插入表值参数时的类型。
  • 如果我也删除,自动生成的DataColumn类型是SqlHierarchyId,错误是一样的
  • 而且当我使用列类型作为字符串时,它的工作原理是什么?并且那里的数据不会被破坏。
  • 我不确定我是否理解您的最后评论。您是说 ADO.Net 会自动将 SQL Server 的 HierarchyId 转换为字符串并为您返回吗?如果是这样的话,那就比我想的还要简单……
猜你喜欢
  • 2011-03-18
  • 2016-09-24
  • 1970-01-01
  • 2015-01-03
  • 1970-01-01
  • 2011-05-23
  • 2021-07-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多