从寻址链接Oracle服务器的SQL Server存储过程返回的无效数据(????)
本文关键字:无效 返回 存储过程 数据 Server 链接 寻址 Oracle 服务器 SQL | 更新日期: 2023-09-27 18:26:58
我们有以下场景:过程是在输出时使用Oracle存储过程返回带有希腊字母的字符串。
Oracle函数(示例)为:
FUNCTION GREEKLATINSTRING (a_latin_name IN VARCHAR2) RETURN VARCHAR2
IS
BEGIN RETURN 'ΣΤΡΟΒΟΛΟΣ/123/ABC'; END;
该函数是从T-SQL存储过程中调用的(请假设所有连接都是100%的,因为我们有其他过程在执行时没有问题)
TSQL存储过程是:
CREATE PROCEDURE [dbo].[GreekLatinString] @NameLatin NVARCHAR(100)
AS
DECLARE @output NVARCHAR(100);
DECLARE @SQL NVARCHAR(MAX);
BEGIN
SET @SQL = N'BEGIN ? := LINKED_SERVER.DB_INSTANCE.GREEKLATINSTRING(?); END;';
EXECUTE(@SQL,
@output OUTPUT ,
@NameGr ) --1Params
AT MYORACLE;
SELECT cast (@output as nvarchar)
END
C#代码并没有什么特别之处——只是简单地获取数据:
dbCommand = CreateCommand();
dbCommand.Transaction = ModelContext.CurrentDBUtils.Transaction;
dbCommand.CommandText = "GreekLatinString";
dbCommand.CommandType = CommandType.StoredProcedure;
SqlParameter param0 = new SqlParameter("NameLatin", nameLatin);
param0.Direction = ParameterDirection.Input;
dbCommand.Parameters.Add(param0);
using (SqlDataAdapter adapter = new SqlDataAdapter(dbCommand as SqlCommand))
{
adapter.Fill(dataset);
}
SQL Server实例排序规则为SQL_Latin1_General_CP1253_CI_AS
,Oracle NLS_LANG
为al32utf8
问题是,每当函数在Oracle中直接执行时,它都会返回它应该返回的值,然而,每当我们从SQL Server存储过程内部的C#调用时,数据集中的输出总是????????
有人能提出这可能是什么原因吗?
不是一个真正的答案,但时间太长,无法发表评论:
当Oracle数据库和Oracle客户端的字符集不同时,Oracle将在两个方向上执行字符数据的转换。如果目标字符集不支持源字符,Oracle将替换一些有效的字符。在许多单字节字符集中,某些东西是?
,在Unicode字符集中,使用u+FFFD,REPLACEMENT CHARACTER
。
请注意,客户端字符集对于客户端机器是不固定的,但可以在连接级别设置。
在这种情况下:
- 字符数据来源于Oracle数据库字符集。该字符数据包括希腊字母
- 字符数据被发送到SQL Server的链接数据库连接所使用的Oracle客户端。如果客户端字符集和数据库字符集不同,则会发生转换
- 从Oracle客户端,字符数据可以通过其他软件层传输。(例如OLE DB。)
- 字符数据被带入SQL Server
- 将显示字符数据。希腊字母成了问号
我的猜测是,第2步中的Oracle客户端字符集是一个不支持希腊字母的单字节字符集,在这一步中,字符被转换为问号。这就是我开始调查的地方。同样,客户端字符集不是为机器设置的,因此不能在SQL Server机器上启动SQLPlus并说"行,问题不在Oracle客户端字符集中。"因为SQLPlus可能使用了与SQL Server不同的东西。
一旦您验证了Oracle客户端字符集是合适的,并且如果您仍然有问题,您就必须找出如何继续工作。我没有任何指导。也许可以针对您正在使用的相同OLE DB驱动程序编写一个简单的客户端应用程序。我不确定。