【问题标题】:Stored procedure Inserts Hebrew characters into an NVARCHAR column, but SELECT shows "?"存储过程 将希伯来字符插入 NVARCHAR 列,但 SELECT 显示“?”
【发布时间】:2017-08-13 01:38:33
【问题描述】:

当我从表中SELECT 时,我存储的数据存储为问号。

@word是我的存储过程中的一个参数,值来自C#代码:

string word = this.Request.Form["word"].ToString();

cmd.Parameters.Add("@word", System.Data.SqlDbType.NVarChar).Value = word;

我的存储过程是这样的:

CREATE PROCEDURE ....
(
   @word nvarchar(500)
   ...
)

Insert into rub_translate (language_id,name)
values (8 ,@word COLLATE HEBREW_CI_AS )

我的数据库和列正在使用 SQL_Latin1_General_CP1_CI_AS 排序规则,我无法更改它们。

谁能给我一个解决方案,我怎样才能通过修改列或表来解决这个问题?

【问题讨论】:

  • 您能告诉我们您将值分配给@word 的代码吗?例如,如果将其设置为字符串文字但忘记了 N 前缀,则会遇到问题。
  • @Bridge @word 是我的存储过程中的一个参数,值来自 C# 代码:string word = this.Request.Form["word"].ToString(); cmd.Parameters.Add("@word", System.Data.SqlDbType.NVarChar).Value = word;
  • OK - 在存储过程定义中,参数是否也是 NVARCHAR 类型的?
  • @Bridge 是的,当然

标签: sql-server tsql unicode collation


【解决方案1】:

为了使其工作,您需要执行以下操作:

  1. 在应用代码中声明输入参数为NVARCHAR(你已经这样做了)

  2. 将存储过程中的输入参数声明为NVARCHAR(这里没有显示代码)

  3. 在定义为NVARCHAR 的表中插入或更新列(您声称是这种情况)

当使用NVARCHAR 时,数据库的默认排序规则是什么并不重要。实际上,当使用NVARCHAR 时,表中列的排序规则是什么都没有关系,至少对于正确插入字符来说不是。

另外,在INSERT 语句中指定COLLATE 关键字是不必要的,无论如何也无济于事。如果您将存储过程输入参数定义为VARCHAR,则字符在进入存储过程时已经转换为?。如果该列实际上定义为 VARCHAR(您没有提供表的 DDL),那么如果排序规则不是 Hebrew_*,那么您无能为力(除了将数据类型更改为 NVARCHAR 或整理到Hebrew_ 一个)。

如果上面列出的这三个项目确实到位,那么最后要检查的是输入值本身。由于这是一个 Web 应用程序,因此页面本身的编码可能设置不正确。您需要在cmd.Parameters.Add("@word", System.Data.SqlDbType.NVarChar).Value = word; 行设置一个断点,并确认word 变量中保存的值包含希伯来字符而不是?s。

另外:您不应该在未指定最大长度/大小的情况下创建字符串参数。默认值为 30(在这种情况下,有时为 1),但存储过程中的参数定义为 NVARCHAR(500)。这可能会导致静默截断(“静默”意味着它不会导致错误,它只会截断值)。相反,您应该始终指定大小。例如:

cmd.Parameters.Add("@word", System.Data.SqlDbType.NVarChar, 500).Value = word;

【讨论】:

    【解决方案2】:

    您可以按原样插入它,因为它是 unicode,然后是 select it with a proper collation:

        declare @test table([name] nvarchar(500) collate Latin1_General_CI_AS);
    
        declare @word nvarchar(500) = N'זה טקסט.';
    
        insert into @test ( [name] ) values  ( @word );
    
        select [t].[name] collate Hebrew_CI_AS from @test as [t]
    

    或者你可以在表格中change the collation of that one column 一起。但请记住,在一个或多个列中使用与数据库不同的排序规则有一个缺点:当您需要比较不同排序规则之间的数据时,您需要将 collat​​e 语句添加到查询中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-29
      • 1970-01-01
      • 1970-01-01
      • 2012-07-28
      • 2012-12-16
      • 2012-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多