The key to this issue is the wording of the error message (emphasis added):
The identifier that starts with
An identifier is a name of an object or item within SQL Server, not a literal string. For example, master
, dbo
, and xp_cmdshell
are all identifiers.
So, you have two options:
Simple fix (but not the best practice)
The issue being with identifiers is a clue that points to the SET QUOTED_IDENTIFIER ON
line. Just changing the ON
to be OFF
will allow this to work. However, you will get an error if there is a space in your path and/or filename pattern (e.g. C:\Program Files (x86)\ ).
Best practice fix (that is still pretty easy)
Use single-quotes instead of double-quotes around the shell command. And since you are creating the command in Dynamic SQL, it needs to be two single-quotes in both instances. So, ...xp_cmdshell ''dir ... /b''...
If there are any spaces in the path itself, then you need double-quotes around the path: ...xp_cmdshell ''dir "..." /b''...
Hence, the full syntax would be:
SET @Query ='master.dbo.xp_cmdshell ''dir "'+ @FilePath + '\' + @SourceFiles +'" /b''';
Putting it into the the full original code, along with a long path name and an extra SELECT
and PRINT
to see what is going on, you get:
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;
Running that gets no errors. The value of @Query
, shown in the "Messages" tab, renders as:
master.dbo.xp_cmdshell 'dir "C:\Users\Solomon\AppData\Local\Microsoft\HelpViewer2.0\TableOfContentsFilterCache\VisualStudio11\en-US\this_is_a_long_file_name.*" /b'
Now, prior to the changes that I suggested, there was an error. The output from the original code (with the same test values) is:
"Results" tab:
129
"Messages" tab:
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
The identifier that starts with 'dir C:\Users\Solomon\AppData\Local\Microsoft\HelpViewer2.0\TableOfContentsFilterCache\VisualStudio11\en-US\this_is_a_long_file_n' is too long. Maximum length is 128.