【发布时间】:2021-02-25 13:33:12
【问题描述】:
存储过程是这样的
CREATE PROCEDURE [dbo].[InsertItemsSPRoc]
-- Add the parameters for the stored procedure here
@File_Name nvarchar(400) = NULL, -- file name to be inserted
@Path_File_Name nvarchar(400) = NULL, -- path file name to be inserted
-- insert in the Media_Files FILETABLE
-- set the specific table holder
set @sql = N'insert into Media_Files (name, file_stream) (SELECT ''' + @File_Name + ''', * FROM OPENROWSET(BULK N''' + @Path_File_Name + ''', SINGLE_BLOB) AS FileData)'
-- execute the combined statement
exec(@sql)
存储过程是通过 MFC 语句调用的,并且当传递的参数是 ANSI(即英文字母)时可以很好地执行。当用户选择文件名由 Unicode 字母组成的文件时出现问题,例如“Ένα Δείγμα.mp4”(在我看来绝对是希腊人),我得到的豁免如下:
无法批量加载,因为无法打开文件“D:??? ??????.mp4”。操作系统错误代码123(文件名、目录名或卷标语法不正确。)。
显然 ODBC 驱动程序正在传递乱码之类的东西。
我尝试使用 MSSM Studio 使用相同的参数调试/执行相同的存储过程,没有问题。
如何在存储过程中传递参数?
【问题讨论】:
-
您还没有说您的 MFC 应用程序是否使用 Unicode 构建。您调用的系统是否期望文件名使用希腊语编码,或者它接受 Unicode 还是接受 UTF-8?
-
MFC 应用程序是使用 Unicode 构建的。此外,SQL Server 2016 数据库一直使用 nvarchar,并且使用希腊语从 MSSM 环境中执行存储过程没有任何缺陷。
-
那个?文件名中的问号通常是在使用 WIndows API 函数 WideCharToMultiByte() 时从 Unicode 转换为“Ansi”(用引号引起来,因为实际上是系统字符集)并且它无法转换字符时发生的情况。 IDK 如何提供帮助。
-
想一想,
BULK关键字后面的 N 标记真的需要吗?我认为最好在''', * FROM OPENROWSET(子句之前进行。也就是说,我宁愿尝试@File_Name + N''', * FROM OPENROWSET(BULK ''' + @Path_File_Name...。 (@Path_File_Name是nvarchar)。最好做一个简单的测试,将@sql文本插入到测试表的nvarchar字段中,然后检查其中的内容。还有,是@sqlnvarchar吗? -
在 N 附近移动并测试后再次出现 nada。在 nvarchar 中插入 @sql 给了我???再次。 Think是ODBC的设置。逐行调试将我带到 dbcore.cpp 第 336 行,其中调用 AFX_ODBC_CALL(::SQLExecDirect(hstmt, reinterpret_cast
(pszSQL), SQL_NTS));制作。我认为应该对 SQLExecDirectW 进行调用,但我不知道如何在我的 stdafx.h 文件中链接 Sqlucode.h
标签: stored-procedures unicode mfc odbc