Incorrect syntax near 'c:' - sql-server

this a sample of test SP i was created befor
when i run it "Incorrect syntax near 'c:'."
create PROCEDURE [dbo].[TextImpotedSP2]
AS
set #path = 'c:temp\TextImpoted0.txt'
SET NOCOUNT ON;
DECLARE #bulk_cmd NVARCHAR(max);
SET #bulk_cmd =
'BULK
INSERT TextImpoted FROM '+ #path1 + '; WITH (FIELDTERMINATOR = ' + ';' ',ROWTERMINATOR = ' + '\n'+ ' )';
EXEC sp_executesql #bulk_cmd
--*************************
any one have any idea?

There seem to be several issues. First, the variable path is never declared, and it's also incorrectly referred to as path1 which needs to be changed. Second, some of the values in the bulk_cmd string needs to be quoted.
A corrected version that should work:
CREATE PROCEDURE [dbo].[TextImpotedSP2]
AS
DECLARE #path NVARCHAR(max)
SET #path = 'c:\temp\TextImpoted0.txt'
SET NOCOUNT ON;
DECLARE #bulk_cmd NVARCHAR(max);
SET #bulk_cmd = '
BULK INSERT TextImpoted
FROM '''+ #path + '''
WITH
(
FIELDTERMINATOR = ' + ''';''' + ',
ROWTERMINATOR = ' + '''\n'''+ '
)';
--PRINT #bulk_cmd
EXEC sp_executesql #bulk_cmd
Also, the path string 'c:temp\TextImpoted0.txt' should probably be 'c:\temp\TextImpoted0.txt' as you might get unexpected results if you use a relative path.
Edit: added the solution to the follow-up question that were posted as an answer...
CREATE PROCEDURE [dbo].[TextImpoted01]
AS
SET NOCOUNT ON;
DECLARE #SQL NVARCHAR(100)
SELECT TOP (1) #SQL = total FROM DealCounter
DECLARE #path NVARCHAR(max)
SET #path = 'c:\temp\TextImpoted'+ #SQL + '.txt'
DECLARE #bulk_cmd NVARCHAR(max);
SET #bulk_cmd = '
BULK INSERT TextImpoted
FROM '''+ #path + '''
WITH
(
FIELDTERMINATOR = ' + ''';''' + ',
ROWTERMINATOR = ' + '''\n'''+ '
)';
--PRINT #bulk_cmd
EXEC sp_executesql #bulk_cmd

change
set #path = 'c:temp\TextImpoted0.txt'
to
set #path = 'c:\temp\TextImpoted0.txt'
the \ is important

Related

SQL Server Linked Server Openquery

This my current code and is working fine.I need the proper syntax to make the fieldname a variable.
For example:
SET #firstname = ''' + #value + ''''
declare #SQL NVARCHAR(4000),#listid nvarchar(50), #value nvarchar(50), #fieldname nvarchar(50)
-- interfering with SELECT statements.
SET NOCOUNT ON;
set #listid = '80000003-1525450413'
set #value = 'dennis4'
set #fieldname = 'firstname'
set #SQL ='Update openquery(QRemote, ''select * from customer WHERE listID = ''''' + #listid + ''''''')
SET firstname = ''' + #value + ''''
EXEC sp_executesql #SQL;
Firstname is a column within Quick Books. All I want is to make it a dynamic parameter. As you can see listID and value are parameters. I would Like to do the following: SET #SQL2 = 'Set #fieldname = ''' + #value + '''' Then I can execute it with EXEC sp_executesql #sql + #sql2.

SQL Server procedure with parameters for table name, field name, and ID of the record

I am trying this in SQL Server and it throws an error:
ALTER PROCEDURE [dbo].[GET_TEXT_DETAIL]
#id UNIQUEIDENTIFIER,
#table VARCHAR(255),
#field VARCHAR(MAX)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql VARCHAR(200)
SET #sql = 'select ' + QUOTENAME(#field) + ' from ' + QUOTENAME(#table) + ' where ID = ' + QUOTENAME(#id)
EXEC (#sql)
END
I get this error:
Msg 207, Level 16, State 1, Line 1
Invalid column name 'CFC2776A-6EE1-E511-A172-005056A218B0'.
Is there any way to do this so I don't have to make a bunch or procedures to pull text from a bunch of different tables?
QUOTENAME has optional second parameter quote char, so you were close and this could be solved by:
... QUOTENAME(#id, '''')
but the most proper way for this case is passing the parameter:
set #cmd = '
SELECT t.' + QUOTENAME(#field) + '
FROM ' + QUOTENAME(#table) + ' t
WHERE t.ID = #ID'
exec sp_executesql #cmd, N'#ID uniqueidentifier', #ID
And server will be able to reuse plan as #srutzsky mentioned. Because #ID is no longer part of a query text and #cmd text remains the same for different #ID (and same #table+#field).
ALTER PROCEDURE [dbo].[GET_TEXT_DETAIL]
(
#id UNIQUEIDENTIFIER,
#table SYSNAME,
#field SYSNAME
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = '
SELECT ' + QUOTENAME(#field) + '
FROM ' + QUOTENAME(#table) + '
WHERE ID = ''' + CAST(#id AS VARCHAR(36)) + ''''
--PRINT #SQL
EXEC sys.sp_executesql #SQL
END

Dynamic T-SQL stored procedure to insert in differents tables

What is the best way to achieve this
INSERT INTO #TableName (#ColumnNames)
EXEC sp_executesql #SQLResult;
Where #TableName, #ColumnNames, #SQLResult are varchar variables
I am trying to avoid do a separate insert for each table.
The best way is to write (or generate) all reqiured procedures for all table. 23 tables times 4 procedures (insert, update, delete and select) that can be generated automatically is nothing in dev time and pain compared to the so called "generic solution".
It's a path to poor perfomance, unreadable code, sql injection hazard and countless debuging hours.
First of all I appreciate all your comments. And I agree that SQL dynamic is a pain to debug (Thanks God, management studio has this possibility). And, of course there are hundreds of different solutions
I solved it in this way finally, more or less I try to explain why this solution of SQL dynamic. The client uses xlsx spreadsheets to enter certain data, so I read the spreadsheets and I insert the (data depends on the spreadsheet to insert into the proper table). Later the data in the tables are exported to XML to send a third party sofware.
SET #SEL = N'';
DECLARE sel_cursor CURSOR
FOR (SELECT sc.name as field
FROM sys.objects so INNER JOIN sys.columns sc ON so.[object_id]=sc.[object_id]
WHERE so.name= #TableName and sc.name not in ('InitDate', 'EndDate', 'Version', 'Status'));
SET #SEL = ''; set #i = 0;
OPEN sel_cursor
FETCH NEXT FROM sel_cursor INTO #field
WHILE ##FETCH_STATUS = 0
BEGIN
set #sel = #sel + ', '+ #field
set #i = 1;
FETCH NEXT FROM sel_cursor INTO #field
END
CLOSE sel_cursor;
DEALLOCATE sel_cursor;
SET #SQL = N''
SET #SQL = #SQL + N'SELECT * INTO XLImport FROM OPENROWSET'
SET #SQL = #SQL + N'('
SET #SQL = #SQL + N'''Microsoft.ACE.OLEDB.12.0'''+','
SET #SQL = #SQL + N'''Excel 12.0 Xml; HDR=YES;'
SET #SQL = #SQL + N'Database='+#file +''''+ ','
SET #SQL = #SQL + N'''select * from ['+ #SheetName + '$]'''+');'
EXEC sp_executesql #SQL
SET #SQL = N'';
SET #SQL = #SQL + N'
SELECT '+''''+CAST(#initDate AS VARCHAR(10))+'''' +', '+ ''''+CAST(#endDate AS VARCHAR(10))+''''
+ ', '+ CAST(#version AS VARCHAR(2)) +', ' +''''+#status+''''
+ #SEL
+' FROM DBO.XLImport '
DECLARE cols_cursor CURSOR
FOR (Select COLUMN_NAME From INFORMATION_SCHEMA.COLUMNS where table_name = #tableName);
SET #SEL = ''; set #i = 0;
OPEN cols_cursor
FETCH NEXT FROM cols_cursor INTO #field
WHILE ##FETCH_STATUS = 0
BEGIN
set #sel = #sel + #field + ', '
set #i = 1;
FETCH NEXT FROM cols_cursor INTO #field
END
CLOSE cols_cursor;
DEALLOCATE cols_cursor;
SET #SEL = LEFT(#SEL, LEN(#SEL) - 1) -- remove last ,
SET #SQL = N''
SET #SQL = #SQL + N'SELECT * INTO XLImport FROM OPENROWSET'
SET #SQL = #SQL + N'('
SET #SQL = #SQL + N'''Microsoft.ACE.OLEDB.12.0'''+','
SET #SQL = #SQL + N'''Excel 12.0 Xml; HDR=YES;'
SET #SQL = #SQL + N'Database='+#file +''''+ ','
SET #SQL = #SQL + N'''select * from ['+ #SheetName + '$]'''+');'
EXEC sp_executesql #SQL
SET #SQLString =
N'INSERT INTO '+ #TableName + '('+ #SEL +') ' + #SQL;
EXEC sp_executesql #SQLString
Use EXECUTE sp_executesql #sql, here is example:
create proc sp_DynamicExcuteStore
#TableName varchar(50),
#ColumnNames varchar(50),
#SQLResult varchar(max)
as
declare #sql nvarchar(max) = '
INSERT INTO '+#TableName+' ('+#ColumnNames+')
EXEC sp_executesql '+#SQLResult
EXECUTE sp_executesql #sql
go
create proc sp_test
as
select 'test' + convert(varchar,RAND())
go
CREATE TABLE [dbo].[Test](
[text1] [nvarchar](500) NULL
) ON [PRIMARY]
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[sp_DynamicExcuteStore]
#TableName = N'Test',
#ColumnNames = N'text1',
#SQLResult = N'proc_test'
SELECT 'Return Value' = #return_value
GO
SELECT TOP 1000 [text1]
FROM [test].[dbo].[Test]

Fetch into Excel sheet and insert into SQL Server 2008 database

I want to import data from my Excel sheet into my SQL Server 2008 database.
I have an Excel sheet that contains different columns :
Service tag | marque | Type | Serial
FGT3456 | DELL | UC | Optiplex 760
and my table has the same structure, but instead of varchar values, I have foreign keys (the IDs)
Example (table material)
Service tag | marque| Type | Serial
FGT3456 | 1 | 18 | 27
What I want to do is to fetch into the column marque in the Excel sheet, get all the marque values, compare the values to those in my table, get all them IDs and in the end insert the Ids into my table material.
I tried this code but it's showing an error
Incorrect syntax near the keyword 'SELECT'.
Incorrect syntax near ')'.
Invalid object name 'SQL'.
This is my code
ALTER PROCEDURE [dbo].[spx_Import]
#SheetName varchar(20),
#FilePath varchar(100),
#HDR varchar(3),
#TableName varchar(50)
AS
BEGIN
DECLARE #SQL nvarchar(1000)
DECLARE #SQL1 nvarchar(1000)
DECLARE #SQL2 nvarchar(1000)
SET #SQL = 'SELECT idMarque FROM MarqueMateriel WHERE marque = SELECT (marque) FROM OPENDATASOURCE'
SET #SQL1 = 'INSERT INTO Material (Service tag) SELECT (service tag) FROM OPENDATASOURCE'
SET #SQL2 = 'INSERT INTO Material (MARQUE) SELECT * FROM '+#SQL''
SET #SQL = #SQL + '(''Microsoft.ACE.OLEDB.12.0'',''Data Source='
SET #SQL = #SQL + #FilePath + ';Extended Properties=''''Excel 12.0;HDR='
SET #SQL = #SQL + #HDR + ''''''')...['
SET #SQL = #SQL + #SheetName + ']'
SET #SQL1 = #SQL1 + '(''Microsoft.ACE.OLEDB.12.0'',''Data Source='
SET #SQL1 = #SQL1 + #FilePath + ';Extended Properties=''''Excel 12.0;HDR='
SET #SQL1 = #SQL1 + #HDR + ''''''')...['
SET #SQL1 = #SQL1 + #SheetName + ']'
SET #SQL1 = #SQL2 + '(''Microsoft.ACE.OLEDB.12.0'',''Data Source='
SET #SQL1 = #SQL2 + #FilePath + ';Extended Properties=''''Excel 12.0;HDR='
SET #SQL1 = #SQL2 + #HDR + ''''''')...['
SET #SQL1 = #SQL2 + #SheetName + ']'
EXEC sp_executesql #SQL
EXEC sp_executesql #SQL1
EXEC sp_executesql #SQL2
END
In the first query #SQL, I retrieve all IDs from the table Material where the name(marque) equals to those in the Excel sheet.
In the 2nd query, #SQL1, I insert the serviceTag values from the Excel sheet into the table
In the last one #SQL2, I insert into the table material the IDs retrieved from the first query
Is my logic correct ?? Is this how I should proceed ?? Please I need help !!
Try changing this line:
SET #SQL2 = 'INSERT INTO Material (MARQUE) SELECT * FROM '+#SQL''
To this - i.e. wrap the #SQL with brackets:
SET #SQL2 = 'INSERT INTO Material (MARQUE) SELECT * FROM (' + #SQL + ')'
I found the solution, it's quite easy and should've think of it from the first time . I imported all the data from my excel sheet into a temp table, and fetch into my mark table get all IDs and insert them directly into my material table.
This is how I achieved this
USE [AxaStock]
GO
ALTER PROCEDURE [dbo].[spx_Import]
#SheetName varchar(20),
#FilePath varchar(100),
#HDR varchar(3),
#TableName varchar(50)
AS
BEGIN
DECLARE #SQL nvarchar(1000)
DECLARE #QUERY nvarchar(1000)
SET #SQL = 'INSERT INTO ESSAIE (serviceTag, periodeGarantie, periodeLeasing, marque, designation, serie, entite, dateDG, nCommande) SELECT serviceTag, periodeGarantie, periodeLeasing, marque, designation, serie, entite, dateDG, nCommande FROM OPENDATASOURCE'
SET #QUERY = 'insert into Materiel (serviceTag, idMarque, idTypeMateriel, idSerieMateriel) select distinct serviceTag, idMarque, idTypeMateriel, '+
'idSerieMateriel from ESSAIEIMPORT ess, MarqueMateriel mm, Serie s, TypeMateriel tm where mm.marque=ess.marque and tm.nomType=ess.designation and '+
's.serieMateriel=ess.serie delete from ESSAIEIMPORT'
SET #SQL = #SQL + '(''Microsoft.ACE.OLEDB.12.0'',''Data Source='
SET #SQL = #SQL + #FilePath + ';Extended Properties=''''Excel 12.0;HDR='
SET #SQL = #SQL + #HDR + ''''''')...['
SET #SQL = #SQL + #SheetName + ']'
EXEC sp_executesql #SQL
EXEC sp_executesql #QUERY
END

I want to use the variable I declared somewhere else but I cannot (simple sql query)

DECLARE #path text;
SET #path = 'c:\bulk'
BULK INSERT [HumanResources].[Employee] FROM -- I Want to use the variable here !!
WITH (
CHECK_CONSTRAINTS,
CODEPAGE='ACP',
DATAFILETYPE='widechar',
FIELDTERMINATOR='\t',
ROWTERMINATOR='\n',
KEEPIDENTITY,
TABLOCK
);
DECLARE #path nvarchar(2000);
SET #path = 'c:\bulk.(extension)';
DECLARE #sql NVARCHAR(MAX) =
'''BULK INSERT [HumanResources].[Employee] FROM' + #path + '
WITH (
CHECK_CONSTRAINTS,
CODEPAGE=''ACP'',
DATAFILETYPE=''widechar'',
FIELDTERMINATOR=''\t'',
ROWTERMINATOR=''\n'',
KEEPIDENTITY,
TABLOCK
)'''
EXECUTE sp_executesql(#sql)
How about this query? Uses dynamic query to execute query. Just aware of the single quotes.
DECLARE #path nvarchar(2000);
DECLARE #sql nvarchar(2000);
SET #path = 'c:\bulk.txt'
set #sql = 'BULK INSERT [HumanResources].[Employee] FROM ''' + #path + ''' WITH (CHECK_CONSTRAINTS, CODEPAGE=''ACP'',
DATAFILETYPE=''widechar'',
FIELDTERMINATOR=''\t'',
ROWTERMINATOR=''\n'',
KEEPIDENTITY,
TABLOCK
)'
print #sql
exec sp_executesql #sql

Resources