存储过程 将希伯来字符插入 NVARCHAR 列,但 SELECT 显示“?”

Stored procedure Inserts Hebrew characters into an NVARCHAR column, but SELECT shows "?"

当我从tableSELECT时,我存储的数据存储为问号。

@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 排序规则,我无法更改它们。

任何人都可以给我一个解决方案我怎样才能通过修改列或 table 来解决这个问题?

您可以按原样插入,因为它是 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 在 table 中全部在一起。但是请记住,在一个或多个列中使用与数据库不同的排序规则有一个缺点:当您需要比较不同排序规则之间的数据时,您需要将 collat​​e 语句添加到查询中。

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

  1. 在app代码中声明入参为NVARCHAR(你已经做到了)

  2. 在存储过程中声明入参为NVARCHAR(此处不显示代码)

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

使用 NVARCHAR 时,数据库的默认排序规则是什么并不重要。实际上,当使用 NVARCHAR 时,table 中列的排序规则是什么并不重要,至少对于正确插入字符而言是这样。

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

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

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

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