我正在尝试使用超过128个字符的SQL Server路径获取目录中的文件列表。它不起作用。
DECLARE
@FilePath varchar(256)='D:\...',--Path with a length more than 128 char
@SourceFiles varchar(100)='Test123456789*.txt',
@Query varchar(1000)
If Object_Id('tempdb.dbo.#FirstTable') Is NULL
CREATE TABLE #FirstTable (Name varchar(256))
SET QUOTED_IDENTIFIER ON
SET @Query ='master.dbo.xp_cmdshell "dir '+ @FilePath + '\' + @SourceFiles +' /b"'
INSERT #FirstTable exec (@Query)
select * from #FirstTable
truncate table #FirstTable
这会出现以下错误:
以'dir D:....'开头的标识符太长。最大长度为128。
答案 0 :(得分:2)
此问题的关键是错误消息的措辞(强调添加):
以
开头的标识符
标识符是SQL Server中对象或项目的名称,不是文字字符串。例如,master
,dbo
和xp_cmdshell
都是标识符。
所以,你有两个选择:
标识符的问题是指向SET QUOTED_IDENTIFIER ON
行的线索。只需将ON
更改为OFF
即可实现此功能。但是,如果路径和/或文件名模式中有空格(例如 C:\ Program Files(x86)\ ),则会出现错误。
在shell命令周围使用单引号而不是双引号。由于您在Dynamic SQL中创建命令,因此在两个实例中都需要两个单引号。所以,...xp_cmdshell ''dir ... /b''...
如果路径本身有空格,那么路径周围需要双引号:...xp_cmdshell ''dir "..." /b''...
因此,完整的语法是:
SET @Query ='master.dbo.xp_cmdshell ''dir "'+ @FilePath + '\' + @SourceFiles +'" /b''';
将其放入完整的原始代码,以及一个长路径名称以及一个额外的SELECT
和PRINT
,看看发生了什么,你得到:
DECLARE @FilePath varchar(256)='C:\Users\Solomon\AppData\Local\Microsoft\HelpViewer2.0\TableOfContentsFilterCache\VisualStudio11\en-US',--Path with a length more than 128 char
@SourceFiles varchar(100)='this_is_a_long_file_name.*',
@Query varchar(1000);
IF (OBJECT_ID(N'tempdb.dbo.#FirstTable') IS NULL)
BEGIN
CREATE TABLE #FirstTable (Name VARCHAR(256));
END;
SET QUOTED_IDENTIFIER ON;
SET @Query ='master.dbo.xp_cmdshell ''dir "'+ @FilePath + '\' + @SourceFiles +'" /b''';
SELECT LEN(@FilePath + '\' + @SourceFiles);
PRINT @Query;
INSERT #FirstTable EXEC(@Query);
SELECT * FROM #FirstTable;
运行它没有错误。 “消息”标签中显示的@Query
的值呈现为:
master.dbo.xp_cmdshell 'dir "C:\Users\Solomon\AppData\Local\Microsoft\HelpViewer2.0\TableOfContentsFilterCache\VisualStudio11\en-US\this_is_a_long_file_name.*" /b'
现在,在我建议的更改之前,出现了错误。原始代码的输出(具有相同的测试值)是:
“结果”标签:
129
“消息”标签:
master.dbo.xp_cmdshell“dir C:\ Users \ Solomon \ AppData \ Local \ Microsoft \ HelpViewer2.0 \ TableOfContentsFilterCache \ VisualStudio11 \ en-US \ this_is_a_long_file_name。* / b”
Msg 103,Level 15,State 4,Line 1
以'dir C:\ Users \ Solomon \ AppData \ Local \ Microsoft \ HelpViewer2.0 \ TableOfContentsFilterCache \ VisualStudio11 \ en-US \ this_is_a_long_file_n'开头的标识符太长。最大长度为128。
答案 1 :(得分:1)
为了好玩,我创建了一个目录C:\Temp\Temporary folder with an unecessarily long name just to be an example etc etc\Temporary folder with an unecessarily long name just to be an example etc etc
(163个字符),并在其中放置了一堆test*.txt
个文件。
以下脚本没有您要描述的问题。
DECLARE @file_path NVARCHAR(256)='C:\Temp\Temporary folder with an unecessarily long name just to be an example etc etc\Temporary folder with an unecessarily long name just to be an example etc etc';
PRINT LEN(@file_path); -- prints 163
DECLARE @src_files NVARCHAR(100)='test*.txt';
DECLARE @dir_cmd NVARCHAR(4000)='DIR "'+@file_path+'\'+@src_files+'" /b';
CREATE TABLE #dir_table(name NVARCHAR(256));
INSERT INTO #dir_table(name) EXEC xp_cmdshell @dir_cmd;
SELECT*FROM #dir_table; -- result is a bunch of test*.txt files
DROP TABLE #dir_table;