Core component of SQL Server for storing, processing, and securing data
The error occurs because @sql goes out of scope or is referenced in a batch where it has not been declared. In the posted script there are also other issues that will prevent it from working as intended.
Key problems and fixes:
- Use single quotes for string literals in T‑SQL
DECLARE @filePath NVARCHAR(MAX) = 'C:\Users\aussi\OneDrive\Desktop\! Complete Family - BMDs_people_EN.csv'; - Ensure everything is in a single batch and
@sqlis declared before every use
Important points:DECLARE @sql NVARCHAR(MAX); DECLARE @filePath NVARCHAR(MAX) = 'C:\Users\aussi\OneDrive\Desktop\! Complete Family - BMDs_people_EN.csv'; DECLARE @tableName NVARCHAR(256) = 'Personal_Details'; DECLARE @colString NVARCHAR(MAX); -- Read header line from file SET @sql = N'SELECT @res = LEFT(BulkColumn, CHARINDEX(CHAR(10), BulkColumn)) FROM OPENROWSET(BULK ''' + @filePath + ''', SINGLE_CLOB) AS x;'; EXEC sp_executesql @sql, N'@res NVARCHAR(MAX) OUTPUT', @res = @colString OUTPUT; -- Build CREATE TABLE statement SELECT @sql = N'DROP TABLE IF EXISTS dbo.' + QUOTENAME(@tableName) + N'; CREATE TABLE dbo.' + QUOTENAME(@tableName) + N' (' + STRING_AGG(N'[' + value + N'] NVARCHAR(MAX)', N',') + N');' FROM STRING_SPLIT(@colString, ','); EXEC(@sql);-
DECLARE @sqlappears once at the top and is reused; there is noGObetween declarations and uses. -
@colStringis passed as an OUTPUT parameter (@res = @colString OUTPUT). -
@tableNameis used withoutdbo.prefix duplication and is quoted withQUOTENAMEto avoid invalid identifiers.
-
- Avoid
GObetween declarations and uses If there is aGObetweenDECLARE @sqlandEXECUTE(@sql), the variable is not visible in the later batch and SQL Server raises “Must declare the scalar variable@sql.” Remove anyGOseparators inside this script.
Once these changes are applied and the script is kept in a single batch, the @sql variable will be recognized and the error Msg 137 will be resolved.
References: