DECLARE #SQL_BULK VARCHAR(MAX)
SET #SQL_BULK = 'BULK INSERT [dbo].[Table]
FROM ''' + #BatchFileName + '''
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR = ''\t'',
ROWTERMINATOR = ''0x0a''
)'
EXEC (#SQL_BULK)
I have this code to do a bulk load. Works fine, but I would like to have the #BatchFileName also in there as a column (each row contains the same value).
Is this possible during the bulk load? Or how can I add it later on in a separate function?
Thanks in advance
i use this script to iterate and bulkinsert files in directory:
create table #x (name varchar(200))
DECLARE #query varchar (1000),#conta int ,#query2 varchar (1000),#NOME varchar(50)
set #conta=1
set #query ='master.dbo.xp_cmdshell "dir '+'C:\directoryname'+'*.csv' +' /b"'
insert #x exec (#query)
delete from #x where name is NULL
select identity(int,1,1) as ID, name into #y from #x
drop table #x
WHILE #conta<221 --number of files
BEGIN
SELECT #NOME=name FROM #y WHERE ID=#conta
set #Query2 ='BULK INSERT [dbo].[tablename] FROM '+ '''C:\directoryname'+#NOME+'''
WITH (
FIELDTERMINATOR = '','',ROWTERMINATOR = ''0x0a'')'
SELECT #query2
exec (#Query2)
set #conta=#conta+1
END
drop table #y
Related
I'm using T-SQL. The goal is to insert multiples files into a database.
If I'm using without a loop, it's working fine.
In the loop, I always get this error:
#InputXML should be declared
My code:
IF OBJECT_ID('TEMPDB..#TEMP_FILES') IS NOT NULL
DROP TABLE #TEMP_FILES
CREATE TABLE #TEMP_FILES
(
FileName VARCHAR(MAX),
DEPTH VARCHAR(MAX),
[FILE] VARCHAR(MAX)
)
INSERT INTO #TEMP_FILES
EXEC master.dbo.xp_DirTree '\\MyServer\MyFolder\',1,1
DELETE FROM #TEMP_FILES WHERE RIGHT(FileName,4) != '.XML'
--
SET QUOTED_IDENTIFIER ON
GO
TRUNCATE Table MyTable2
DECLARE #InputXML XML
DECLARE #FILENAME VARCHAR(MAX),#SQL VARCHAR(MAX)
WHILE EXISTS(SELECT * FROM #TEMP_FILES)
BEGIN
SET #FILENAME = (SELECT TOP 1 FileName FROM #TEMP_FILES)
SET #sql = 'SELECT #InputXML = CAST(x AS XML) FROM OPENROWSET(BULK \\MyServer\MyFolder\'''+ #FILENAME +''', SINGLE_BLOB) AS T(x)
INSERT INTO MyTable2 ([id],[version], [name], [listId], [listCode])
SELECT
product.value(''(#id)[1]'', ''NVARCHAR(10)''),
product.value(''(#version)[1]'', ''NVARCHAR(14)''),
product.value(''(name[1])'', ''NVARCHAR(255)''),
product.value(''(listId[1])'', ''NVARCHAR(9)''),
product.value(''(listCode[1])'', ''NVARCHAR(10)'')
FROM #InputXML.nodes(''xxx/values/value'') AS X(product)'
EXEC(#SQL)
DELETE FROM #TEMP_FILES
WHERE FileName = #FILENAME
END
You need to declare the variable inside the dynamic SQL (which should be nvarchar not varchar). You should also use QUOTENAME to ensure no issues with the filename:
DECLARE #sql nvarchar(max) = N'
DECLARE #InputXML XML;
SELECT #InputXML = CAST(x AS XML) FROM OPENROWSET(BULK ' + QUOTENAME(N'\\MyServer\MyFolder\' + #FILENAME, '''') + N', SINGLE_BLOB) AS T(x)
INSERT INTO MyTable2 ([id],[version], [name], [listId], [listCode])
SELECT
product.value(''(#id)[1]'', ''NVARCHAR(10)''),
product.value(''(#version)[1]'', ''NVARCHAR(14)''),
product.value(''(name[1])'', ''NVARCHAR(255)''),
product.value(''(listId[1])'', ''NVARCHAR(9)''),
product.value(''(listCode[1])'', ''NVARCHAR(10)'')
FROM #InputXML.nodes(''xxx/values/value'') AS X(product)'
I will say though, that I urge you to find another method to load files into SQL Server. Dynamic OPENROWSET, especially from user input, is not advisable. Bulk Insert or BCP may be an option.
I am trying to write a query that needs to call a stored procedure. But it always throws an error:
Unknown object type 'TABLEIXICHistoricalData' used in a CREATE, DROP, or ALTER statement.
This is query:
USE ETLCourse
DECLARE #LOOP TABLE
(
ID INT IDENTITY(1,1),
TableName NVARCHAR(100)
)
INSERT INTO #LOOP (TableName)
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '%_Stocks%'
DECLARE #b INT = 1, #m INT, #t NVARCHAR(100)
SELECT #m = MAX(ID) FROM #LOOP
WHILE #b <= #m
BEGIN
SELECT #t = TableName
FROM #LOOP
WHERE ID = #b
EXECUTE [dbo].[stp_BuildNormalizedTable] #t
SET #b = #b + 1
END
and here is the procedure:
ALTER PROCEDURE [dbo].[stp_BuildNormalizedTable]
#table NVARCHAR(100)
AS
BEGIN
DECLARE #cleanTable NVARCHAR(100),
#s NVARCHAR(MAX)
SET #cleanTable = REPLACE(#table, '_Stocks', 'HistoricalData')
SET #s = 'CREATE TABLE' + #cleanTable + '(ID INT IDENTITY(1,1), Price DECIMAL(13, 4), PriceDate DATE)
INSERT INTO' + #cleanTable + '(Price,PriceDate) SELECT [Adj Close],[Date] FROM'
+ #table + ' ORDER BY Date ASC'
--PRINT #s
EXECUTE sp_executesql #s
END
It should copy two specific column and create a new table by using #Loop table and procedure
You need to add 'space' after 'create table' and 'insert into' and 'from'
declare #s nvarchar(max)
declare #cleantable nvarchar(100)
declare #table nvarchar(100)
set #cleantable = 'aaa'
set #table = 'bbb'
SET #s = 'CREATE TABLE' + #cleanTable + '(ID INT IDENTITY(1,1),Price Decimal(13,4),PriceDate DATE)
Insert into' + #cleanTable
+ '(Price,PriceDate) SELECT [Adj Close],[Date] FROM'
+ #table + ' ORDER BY Date ASC'
print #s
Output:
CREATE TABLEaaa(ID INT IDENTITY(1,1),Price Decimal(13,4),PriceDate DATE)
Insert intoaaa(Price,PriceDate) SELECT [Adj Close],[Date] FROMbbb ORDER BY Date ASC
Use 'print' to check your query.
I am trying to import .txt files daily into sql server 2008 table and I want to automate it
so in steps:
1- I receive 2 files daily with name hazem.log.date and hazem.log.date2
2- I need to have a way to import them daily and automatically
3- I will use the job, but which command or query should be used in this case?
Try running below through SQLServer jobs..
BULK INSERT dbo.ImportTest
FROM 'C:\ImportData.txt' --replace name of your files
WITH ( FIELDTERMINATOR =',', FIRSTROW = 2 )
you also can use
bcp dbo.ImportTest in 'C:\ImportData.txt' -T -SserverName\instanceName
For Mutiple files..you can do like this..
1.Create a stored proc first..
Create procedure usp_ImportMultipleFilesBCP #servername varchar(128),
#DatabaseName varchar(128), #filepath varchar(500), #pattern varchar(100),
#TableName varchar(128)
as
declare #query varchar(1000)
declare #max1 int
declare #count1 int
Declare #filename varchar(100)
set #count1 =0
create table #x (name varchar(200))
set #query ='master.dbo.xp_cmdshell "dir '+#filepath+#pattern +' /b"'
insert #x exec (#query)
delete from #x where name is NULL
select identity(int,1,1) as ID, name into #y from #x
drop table #x
set #max1 = (select max(ID) from #y)
--print #max1
--print #count1
--select * from #y
While #count1 <= #max1
begin
set #count1=#count1+1
set #filename = (select name from #y where [id] = #count1)
set #Query ='bcp "'+ #databasename+'.dbo.'+#Tablename + '"
in "'+ #Filepath+#Filename+'" -S' + #servername + ' -T -c -r\n -t,'
set #Query = 'MASTER.DBO.xp_cmdshell '+ "'"+ #query +"'"
--print #query
EXEC ( #query)
insert into logtable (query) select #query
end
2.Now run above sp to import all files of desired extension
Exec usp_ImportMultipleFilesBCP 'SQL','Bank','c:\Myimport\','*.csv','Account'--table account
Note:
You will need to enable Xp_cmdshell
References:
https://www.mssqltips.com/sqlservertip/1207/different-options-for-importing-data-into-sql-server/
http://www.databasejournal.com/features/mssql/article.php/3325701/Import-multiple-Files-to-SQL-Server-using-T-SQL.htm
I am using T-SQL
I have a few excel files located here: C:\MyFiles\
I want to remove all the apostrophes in the file names in that directory.
Now to remove apostrophes one would use code like this.
update MyTable
set FileName= replace(FileName, '''', '')
If I had all the file name in the DB it would be easy to do with the code above. But I need to update the file names that are located on disk.
How would I go about doing this with T-SQL?
It must be T-SQL because I need to add it to my existing code in my Stored Procedure.
SET NOCOUNT ON;
CREATE TABLE #FileList
(
FileID INT IDENTITY(1, 1)
,Line VARCHAR(512)
)
CREATE TABLE #temp
(
isFileThere BIT
,isDirectory BIT
,parentDirExists BIT
)
DECLARE #Command VARCHAR(1024)
, #RowCount INT
, #counter INT
, #FileName VARCHAR(1024)
, #FileExists BIT
SET #Command = 'dir C:\MyFiles\ /A-D /B'
PRINT #Command
INSERT #FileList
EXEC master.dbo.xp_cmdshell #Command
DELETE FROM #FileList
WHERE Line IS NULL
SELECT #RowCount = COUNT(*)
FROM [#FileList]
SET #counter = 1
WHILE ( #counter <= #RowCount )
BEGIN
SELECT #FileName = [Line]
FROM [#FileList]
WHERE [FileID] = #counter
SET #Command = 'C:\MyFiles\' + #FileName + ''
PRINT #Command
INSERT [#temp]
EXEC master.dbo.xp_fileExist #Command
SELECT #FileExists = [isFileThere]
FROM [#temp]
IF #FileExists = 1
AND CHARINDEX('''', #FileName) > 0
SET #Command = 'REN "C:\MyFiles\' + #FileName + '" "'
+ REPLACE(#FileName, '''', '') + '"'
ELSE
SET #Command = ''
SET #counter = #counter + 1
PRINT #Command
IF LEN(#Command) > 0
EXEC master.dbo.xp_cmdshell #Command
END
DROP TABLE #FileList
DROP TABLE [#temp]
First you need to enable xp_cmdshell
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
Then you can use sp_cmdshell to retrieve the files names from the directory
Declare #Directory TABLE (Files Varchar(MAX))
Declare #File TABLE (Name varchar(MAX))
INSERT INTO #Directory
EXEC XP_CMDSHELL 'DIR "D:"'
Insert into #File
Select reverse(LEFT(reverse(Files),charindex(' ' ,reverse(Files)))) from #Directory
Select * from #FILE
Now you get the file names in the table variable #FILE and use function like replace or your own custom function to replace apostrophes with the exact filename
Try this it will work for you
1) Create a sp as mentioned below
CREATE PROCEDURE dbo.ListPathsXML
#FileSpec VARCHAR(2000),
#order VARCHAR (80) = '/O-D',--sort by date time oldest first
#xmlFileList XML OUTPUT
AS
DECLARE #myfiles TABLE (MyID INT IDENTITY(1,1) PRIMARY KEY, FullPath VARCHAR(2000))
DECLARE #CommandLine VARCHAR(4000)
IF #order IS NOT NULL -- abort if the order is silly
BEGIN
SELECT #CommandLine =LEFT('dir "' + #FileSpec + '" /A-D /B /S '+#order,4000)
INSERT INTO #MyFiles (FullPath)
EXECUTE xp_cmdshell #CommandLine
DELETE FROM #MyFiles WHERE fullpath IS NULL
OR fullpath = 'File Not Found'
END
SET #xmlFileList = (SELECT fullpath FROM #MyFiles
FOR
XML PATH('thefile'),
ROOT('thefiles'),
TYPE)
2) and then give a name of directory where you want to replace the name of files
DECLARE #LotsOfText NVARCHAR(MAX),
#ii INT,
#iiMax INT,
#File VARCHAR(2000),
#Command NVARCHAR(4000)
DECLARE #files TABLE (MyID INT IDENTITY(1,1) PRIMARY KEY, [Path] VARCHAR(2000))
DECLARE #FileList XML
EXECUTE ListPathsXML 'D:\QAconfig\',
DEFAULT , #XMLFileList = #FileList OUTPUT
INSERT INTO #files(path)
SELECT x.thefile.value('fullpath[1]', 'varchar(2000)') AS [path]
FROM #FileList.nodes('//thefiles/thefile') AS x ( thefile )
--don't look at the current errorlog!
SELECT #ii=1, #iiMax=MAX(MyID) FROM #Files
WHILE #ii<=#iiMax
BEGIN
SELECT #File= [path] FROM #files WHERE MyID=#ii
print #File
SELECT #command='EXEC master..xp_cmdshell' + '''MOVE '+ Replace(#FILE,'''','''''') + ' ' +REPLACE(#FILE,'''','') +''''
print #command
EXECUTE sp_ExecuteSQL #command--, N'#lotsOfText nvarchar(max) output ',#lotsoftext output
SELECT #ii=#ii+1
END
Basically i want to be able to dynamically create a temp table based off of an existing table, and then insert values into the temp table, and select the inserted values.
i've got the part where i can create the temp table working just fine, it's just that inserting and selecting form it aren't working too well.
here's my current code.
declare #table table
(
OrdinalPosition int,
ColumnName nvarchar(255),
DataType nvarchar(50),
MaxChar int,
Nullable nvarchar(5)
)
declare #i int
declare #count int
declare #colname nvarchar(255), #datatype nvarchar(50), #maxchar int
declare #string nvarchar(max)
declare #tblname nvarchar(100)
set #tblname='Projects'
set #string='create table #' + #tblname + ' ('
insert into #table
(
OrdinalPosition,
ColumnName,
DataType,
MaxChar,
Nullable
)
SELECT
ORDINAL_POSITION ,
COLUMN_NAME ,
DATA_TYPE ,
CHARACTER_MAXIMUM_LENGTH ,
IS_NULLABLE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #tblname
set #i=1
select #count=count(*) from #table
while (#i<=#count)
begin
select #colname=ColumnName from #table where OrdinalPosition=#i
select #datatype=DataType from #table where OrdinalPosition=#i
select #maxchar=MaxChar from #table where OrdinalPosition=#i
if (#maxchar is null)
begin
set #string = #string + #colname + ' ' + #datatype
end
else
begin
set #string = #string + #colname + ' ' + #datatype + '(' + cast(#maxchar as nvarchar(20)) + ')'
end
if (#i=#count)
begin
set #string = #string + ')'
end
else
begin
set #string = #string + ', '
end
set #i=#i+1
end
select #string
exec(#string)
set #string='
insert into #Projects (pk_prID, prWASSN_ID, prProjectStatus, prBusinessUnit, prServiceLine, prStudyTypeCode, prStudyNumber, prTimePoint, prStudyDirector,
prGroupLeader, prBookedDate, prBookedAmount, prConsumed, prBudgetedHours, prFinalReport, prFinalYear, prFinalMonth, prStartQA,
prLabWorkStarted, prLabWorkCompleted, prProjImpDate, prCompanyName, prCompanyNumber, prIsFTE, prRevisedDeadlineDate, prProjectFinalized,
prBookedYear, prBookedMonth, prCRMQuoteID, prLineItemNumber, prDraftReport, prInternalTargetDeadlineDate, prProtocolSignedDate,
prDataToRWS, prRWSWorkStarted, prFirstDraftToPL, prFirstDraftToQA, prArchivedDate, prToPLForQACommentReview,
prAnticipatedProjectArchiveDate, prToQAWithPLCommentResponse, prProjectReactivatedDate, prQAFinishDate, prSecondDraftReportToClient)
select *
from cube.Projects'
select #string
exec (#string)
set #string='select * from #Projects'
exec (#string)
this is the error that i get:
(44 row(s) affected)
(1 row(s) affected)
(1 row(s) affected)
Msg 208, Level 16, State 0, Line 2
Invalid object name '#Projects'.
Msg 208, Level 16, State 0, Line 1
Invalid object name '#Projects'.
Try to name the table with two ##, this will create a global temp table. It could be an issue with scoping, you might be creating the table with exec but it is not visible when it comes back.
When you call exec I believe it executes outside the context where your temp table was declared I believe if you appended your strings together and executed as one call to exec it would succeed. The other option is to use a global temp table with ## as the prefix instead of #.