BULK INSERT from variable Date Filename - ERROR - sql

I am trying to do an insert of a text file that contain datetime in filename.
declare #V_SQL varchar(100)
set #V_SQL = (select REPLACE(REPLACE(CONVERT(VARCHAR,getdate()-1,106), ' ',''), ',',''))
BULK INSERT [dbo].[test] FROM '"E:\test_"+ #V_SQL +".txt"'
WITH
(
FIELDTERMINATOR = '|',
ROWTERMINATOR = '0x0a'
)
GO
When I run the above I get following message - BULK INSERT [dbo].[test] FROM '"E:\test_"+ #V_SQL +".txt"'

You can't put a variable or an expression there. You'll need to use dynamic SQL.
DECLARE #sql nvarchar(max) = N'BULK INSERT dbo.test FROM '''
+ 'c:\test_'
+ REPLACE(CONVERT(char(11), DATEADD(DAY,-1,GETDATE()), 13),' ','')
+ ''' WITH
(
FIELDTERMINATOR = ''|'',
ROWTERMINATOR = ''0x0a''
);';
PRINT #sql;
--EXEC sys.sp_executesql #sql;
I strongly recommend:
not using shorthand for date operations (e.g. GETDATE()-1)
always declaring lengths for variable data types like varchar.

Related

BULK INSERT with variable file name in SET statement

I am trying to do a bulk insert but the #CSVPath is not resolving.
declare #path varchar(255)
set #path = 'C\CSVPath.csv';
BULK INSERT #mytable FROM #CSVPath <-- Error line
WITH ( FIELDTERMINATOR = ',', ROWTERMINATOR = '\n' );
I've tried
FROM ''' + #CSVpath + '''
If I hard code the path it works. If I wrap it all in a SET statement and execute it works.
declare #sql varchar(max)
set #sql = 'BULK INSERT #mytable FROM ''' + #CSVPath + ''' WITH ...
exec (#sql)
However, I cannot do it this way and need to it the first method but it doesn't seem to be resolving and cannot figure how to get it to work.
properly When running query dynamics, the compiler stores the values of the variable, but does not normally name the table or address through the variable.
BULK INSERT #mytable
FROM 'C:\test.csv'
WITH
(
FIRSTROW = 2, -- as 1st one is header
FIELDTERMINATOR = ',', -- field delimiter
ROWTERMINATOR = '\n', -- next row
TABLOCK
)

SQL Bulk Insert in a loop

I'm trying run BULK INSERT in a loop. Loop through each file in some directory ends with no of particular file. Below is my solution
DECLARE #startFlag INT
DECLARE #endFlag INT
DECLARE #fileName varchar(50)
SET #startFlag = 1
SET #endFlag = 10
WHILE (#startFlag <= #endFlag)
BEGIN
SET #fileName = 'c:\path to file\filename_' + cast(#startFlag as varchar) + '.csv'
BULK
INSERT dbo.Intraday
FROM #fileName
WITH
(
FIELDTERMINATOR = '|',
ROWTERMINATOR = '\n'
)
SET #startFlag = #startFlag + 1
END
GO
but seems don't work. Is there anything I've overlooked or another missing stuff I can fix this issue?
You can't use variables or expressions all the places you might like in TSQL. You'll have to use dynamic SQL:
declare #fileName nvarchar(2000) = 'foo.csv'
SET #fileName = 'foo'
declare #sql nvarchar(max) = N'
BULK
INSERT dbo.Intraday
FROM '''+#fileName+'''
WITH
(
FIELDTERMINATOR = ''|'',
ROWTERMINATOR = ''\n''
)';
exec (#sql);
you can not use veritable name after From. you have to provide the name of file after from clause not variable. so you need to make complete bulk insert statement dynamically. please refer below sample code -
declare #sql nvarchar(max)
DECLARE #fileName varchar(50)
set #fileName ='C:\Input.txt'
set #sql = 'BULK
INSERT dbo.Intraday
FROM ''' + #fileName + '''
WITH
(
FIELDTERMINATOR = ''|'',
ROWTERMINATOR = ''\n''
)'
exec(#sql)

How to prevent SQL injection in dynamic sql for bulk insert?

I'm using dynamic SQL for bulk insert with a parameter (Bulk insert using stored procedure).
DECLARE #sql NVARCHAR(4000) = 'BULK INSERT TblValues FROM ''' + #FileName + ''' WITH ( FIELDTERMINATOR ='','', ROWTERMINATOR =''\n'' )';
EXEC(#sql);
But... How to avoid SQL injection?
You could use QUOTENAME to surround the file name in single quotes:
DECLARE #sql NVARCHAR(4000) = 'BULK INSERT TblValues FROM ' + QUOTENAME(#FileName,'''') + ' WITH ( FIELDTERMINATOR ='','', ROWTERMINATOR =''\n'' )';
EXEC (#sql);
One way would be to retrieve the file name versus pass it in... something like
DECLARE #fileLocation VARCHAR(128) = '\\some\folder\location'
IF OBJECT_ID('tempdb..#FileNames') IS NOT NULL DROP TABLE #FileNames
CREATE TABLE #FileNames(
id int IDENTITY(1,1)
,subdirectory nvarchar(512)
,depth int
,isfile bit)
INSERT #FileNames(subdirectory,depth,isfile)
EXEC xp_dirtree #fileLocation, 1, 1
Then, in #FileNames will be all the files in that directory (where isfile = 1 of course). Then you can simply query the file name(s) from the temp table.

transact-sql newbie-error- trying to bulk insert data from multiple files into sql server database

I am trying to insert data from multiple files into SQL Server. This is the code I am using--
DECLARE #MyCounter int;
DECLARE #Fileprefix nvarchar, #Filesuffix nvarchar, #fullname nvarchar, #Counter_string nvarchar;
SET #MyCounter = 1;
SET #Fileprefix= 'C:\Arvind_gpd\patents\';
SET #Filesuffix='data_corrected.csv';
WHILE (#MyCounter < 10)
BEGIN;
Set #Counter_string= Cast(#MyCounter AS varchar(1) );
Set #fullname = (#Fileprefix+ #Counter_string + #Filesuffix );
BULK INSERT GooglePatentsIndividualDec2012.dbo.patent
FROM #fullname WITH ( DATAFILETYPE = 'char', FIELDTERMINATOR = '^', ROWTERMINATOR = '\n' );
SET #MyCounter = #MyCounter + 1;
END;
GO
However I am getting these error messages--
Incorrect syntax near #fullname. Expecting Integer, String, TEXT_LEX.....
Incorrect syntax near DATAFILETYPE. Expecting SELECT or '('
What am I doing wrong in the above query?
You cannot use a variable as a filename. According to the syntax described in MSDN it has to be a constant.
You may create the command and use EXEC to execute it.
set #Command = 'BULK INSERT GooglePatentsIndividualDec2012.dbo.patent '
set #Command = #Command + 'FROM '''+#fullname+''' WITH ( '
set #Command = #Command + 'DATAFILETYPE = ''char'', '
set #Command = #Command ΓΌ 'FIELDTERMINATOR = ''^'', ROWTERMINATOR = ''\n'' )'
EXEC (#Command)
You cannot use a variable as a table name. If you want to use a variable you have to create a string and use the EXEC function like this:
DECLARE #fullname nvarchar, #sql nvarchar
SET #sql = 'SELECT * FROM ' + #fullname+ ' WHERE id = 1'
EXEC(#sql)

BULK INSERT with variable file name

i am trying to bulk insert into Db using sql server 2005
Below is the code.
declare #path varchar(500)
set #path = 'E:\Support\test.csv';
Create table #mytable( name varchar(max), class varchar(max), roll varchar(max) )
BULK INSERT #mytable FROM #path <-- Error line
WITH ( FIELDTERMINATOR = ',', ROWTERMINATOR = '\n' );
Go
select * from #mytable
drop table #mytable
Problem: issue is that my file path is dynamic and comes from a variable instead of hard coding which is not working
If i change the error line to below it works
BULK INSERT #mytable FROM 'E:\Support\test.csv';
Please advise how to fix this
Try to use Dynamic SQL:
declare #sql varchar(max)
set #sql = 'BULK INSERT #mytable FROM ''' + #path + ''' WITH ...
exec (#sql)
DECLARE #path varchar(50) = 'D:\ARQUIVOS_CARGAS\CABOS\FILE.prn'
DECLARE #SQL_BULK VARCHAR(MAX)
SET #SQL_BULK = 'BULK INSERT #TAB FROM ''' + #path + ''' WITH
(
CODEPAGE = ''ACP'',
FIRSTROW = 1,
FIELDTERMINATOR = ''tab'',
ROWTERMINATOR = ''0x0a'',
KEEPNULLS
)'
EXEC (#SQL_BULK)