Incorrect syntax near '.' when querying SQL Server from Excel - sql-server

I've successfully connected to our SQL Server from VBscript from an Excel file. I was able to run the following query and return the expected results, but now I'm getting an error:
Incorrect syntax near '.'
The only thing I've changed was adding string breaks, ending the line with a quote, ampersand, space, hyphen to continue the query on the following line.
I've tried all the recommendations I could find on Stack Overflow,e.g. deleting and re-adding white spaces, copy/paste into a notepad to find special characters, re-adding all the '.' and manually adding CR.
Any other thoughts? Should I be using a different syntax to break up my query string?
SELECT
IM_BARCOD.BARCOD, IM_PRC.PRC_1, IM_INV.QTY_AVAIL, IM_ITEM.DESCR,
IM_INV.LOC_ID, IM_INV.ITEM_NO" & _
FROM
BCEXP.dbo.IM_BARCOD
INNER JOIN
BCEXP.dbo.IM_INV ON IM_INV.ITEM_NO = IM_BARCOD.ITEM_NO
INNER JOIN
BCEXP.dbo.IM_PRC ON IM_INV.ITEM_NO = IM_PRC.ITEM_NO
INNER JOIN
BCEXP.dbo.IM_ITEM ON IM_INV.ITEM_NO = IM_ITEM.ITEM_NO" & _
WHERE
(IM_ITEM.TRK_METH = 'N' AND IM_INV.LOC_ID = 'MAIN')" & _
AND(IM_ITEM.ITEM_VEND_NO = 'OSPR' OR IM_ITEM.ITEM_VEND_NO = 'ENZEES'
OR IM_ITEM.ITEM_VEND_NO = 'WM')

As you have noticed, it is difficult to get SQL correct when you're using a string like that. I assume you are using an older version of Visual Studio, so one option to make the SQL more readable is to use an XML literal, like this:
Dim sql = <sql>
SELECT     im_barcod.barcod,
           im_prc.prc_1,
           im_inv.qty_avail,
           im_item.descr,
           im_inv.loc_id,
           im_inv.item_nofrom bcexp.dbo.im_barcod
inner JOIN bcexp.dbo.im_inv
ON         im_inv.item_no=im_barcod.item_no
INNER JOIN bcexp.dbo.im_prc
ON         im_inv.item_no=im_prc.item_no
INNER JOIN bcexp.dbo.im_item
ON         im_inv.item_no=im_item.item_nowhere(im_item.trk_meth='N'
AND        im_inv.loc_id='MAIN')
AND       (
                      im_item.item_vend_no='OSPR'
           OR         im_item.item_vend_no='ENZEES'
           OR         im_item.item_vend_no='WM')
</sql>.Value()
The name of the tag <sql> is not important. Your indentation may vary from that shown - I used an online SQL formatter (Instant SQL Formatter this time).
Now you can see that it all goes horribly wrong around
im_inv.item_no=im_item.item_nowhere(im_item.trk_meth='N'
because there is a space missing after "item_no".

Related

VB.NET, SQL Server and list of dates

I have a query that takes as a parameter a list of dates. In VB.NET the dates are in a string ArrayList and I am using the String.Join() method to get them in a comma delimited list. The problem is when I do that double quotes are put at the start and end of the string and SQL complains about that (I think; see below). How can I get a list of date from a string ArrayList without the quote.
My arraylist contains these values:
'2020-08-30'
'2020-08-27'
'2020-09-28'
'2020-09-09'
'2020-08-31'
'2020-08-29'
when I join them using String.Join(",", sDates) I get the following:
"'2020-08-30','2020-08-27','2020-09-28','2020-09-09','2020-08-31','2020-08-29'"
and when I use that in a parameter query it gets rejected.
comm.Parameters.AddWithValue("#dates", String.Join(",", sDates))
sql contains the following"
...where pj.ProjectName =#projectname And tcd.Date in (#dates)
Exact error I get is
System.Data.SqlClient.SqlException
HResult=0x80131904
Message=Incorrect syntax near ','.
Source=.Net SqlClient Data Provider
Any advice?
This error message:
Incorrect syntax near ','
Is not caused by the way you've done your IN. It is caused by something else, such as a misplaced comma in a select block:
SELECT , a FROM x
^
The way you've done your IN won't work either, because it's conceptually the same as writing this:
SELECT * FROM table WHERE dateColumn IN ('''2000-01-01'',''2000-02-01''')
There is no such date with a string value of '2000-01-01','2000-02-01'.
If you want to use IN in the style you're attempting here, you have to add a parameter per date value and set it up accordingly:
sqlCommand.CommandText = "SELECT * FROM table WHERE dateCol IN("
Dim p = 0
For Each d as DateTime in MyDateList
sqlCommand.CommandText &= "#p" & i & "," 'concat param placeholder on
sqlCommand.Parameters.AddWithValue("#p" & i, d)
i += 1
Next d
sqlCommand.CommandText = sqlCommand.CommandText.TrimEnd(","c) & ")" 'get rid of trailing comma and close the IN brackets
This will generate an sql like
SELECT * FROM table WHERE dateCol IN (#p0,#p1,#p2)
with 3 parameters, and a populated parameters collection. You've already been pointed to Joel's blog about AddWithValue, so I won't repeat it.. But i did want to say that the way you've presented your question implies you have a list of strings, not datetimes. You should definitely make sure your list has DateTimes in, and your db column should be a date based type, not a string based type

How to escape from a string with single quote inside to do an insert?

I'm trying to insert N"Pepito Malasanya O'Dhogerty" on Python 3 but cannot escape the single quote, the error on PYODBC is:
"Incorrect syntaxis".
I know that I have to add another one (O''Dhogerty) but I did my best trying everything I saw and didn't fix it.
That's what I did so far:
string = string.replace("'", "\\'\\'")
UPDATED:
It didn't work because I was using 'N' front of the string (because I have characters like "ª")
Now I have:
row[0] = row[0].replace("'","\'\'")
pyodbc.ProgrammingError: ('42S22', "[42S22] [Microsoft][ODBC SQL Server Driver][SQL Server]El nombre de columna 'Pepito Malasanya O''Dhogerty' no es válido. (207) (SQ
LExecDirectW)")
What am I doing wrong? I'm going to check parameterized query as you said.
SOLUTION:
I was doing the execute method with '{}'.format... but it doesnt work with inserts with such special characters, i changed to cursor.execute("INSERT INTO table VALUES (?,?,?,?,?,?,?,?,?,?)",value1, value2....) and ANY PROBLEM
Thanks anyway for the help

Escaping an ampersand in SQL Server Full-Text Search query using CONTAINSTABLE

I have a very peculiar case. My ASP.NET page calls a stored procedure of ours that performs a Full-Text Search query on our database. Some of the commonly searched strings include an ampersand because a few brands of our products (well-known brands, too) have an & in their name.
It turns out that in a certain case I get no results unless I escape the ampersand (\&), and in a certain other case I get no results only if I escape the ampersand.
I don't know if this is relevant, but (without giving out the brand names) one ends in &b and the other one in &c.
Is it possible that these strings (&b or &c) have some special meaning of their own? And that by escaping them I'm actually passing a special string to T-SQL?
EDIT
Additional info: after further testing, I proved that the error is in the stored procedure itself. Calling it with & or \& yields different results.
I'll try to post selected parts of the stored procedures. I won't post it all, because most of it isn't really relevant.
The vParamBuca parameter is the one that causes the troubles. Values could be 'word&letter' or word\&letter.
SET #ricercaA = '''FORMSOF(INFLECTIONAL,"' +
REPLACE(LTRIM(RTRIM(#vParamBuca)),' ', '") AND FORMSOF(INFLECTIONAL,"') + '")'''
The variable #ricercaA is then used to create the query string:
[...]
FROM Products AS FT_TBL
LEFT OUTER JOIN CONTAINSTABLE (Products, Sign1, '+ #ricercaA + ') AS ColSign1_0 ON FT_TBL.ID = ColSign1_0.[KEY]
LEFT OUTER JOIN CONTAINSTABLE (Products, ManufacturerAdditionalText, '+ #ricercaA + ') AS ColManufacturerAdditionalText_0 ON FT_TBL.ID = ColManufacturerAdditionalText_0.[KEY]
LEFT OUTER JOIN CONTAINSTABLE (Products, ManufacturerForSearch, '+ #ricercaA + ') AS ColManufacturer_0 ON FT_TBL.ID = ColManufacturer_0.[KEY]
LEFT OUTER JOIN CONTAINSTABLE (Products, TuttaLaRiga, '+ #ricercaA + ') AS ColTuttaLaRiga_0 ON FT_TBL.ID = ColTuttaLaRiga_0.[KEY]
[...]
EDIT 2
Many thanks to #srutzky for pointing me in the right direction! In the meanwhile, I also found a data inconsistency where one of the brands with the & in its name was modified not to have the &, and the other one wasn't modified (bottom line, my current problem is caused by that: a partial fix that was made by someone in the past).
Anyway, back on track. Now I understand that the & character in the CONTAINSTABLE function is treated as a logical AND (non bitwise).
I still need a solution for that. This answer gives a solution that doesn't work for me (the conditions are not the same as mine). How could I perform a CONTAINSTABLE search for a string with an ampersand in it? Preferably without having to transform the ampersand to another safe character?
The odd behavior you are seeing is most likely due to the CONTAINS and CONTAINSTABLE functions (both used with SQL Server's Full Text Search feature) using the ampersand ( & ) character as equivalent to the AND operator. The following statement is taken from the documentation for CONTAINS:
The ampersand symbol (&) may be used instead of the AND keyword to represent the AND operator.
There is no mention of there being any escape character for it (and a back-slash isn't typically an escape character in SQL anyway).
UPDATE
Based on the information now provided in "Edit 2" of the Question, and additional research, I would say that you do not need to escape anything. It seems that putting the search phrases in double-quotes (as a result of using FORMSOF) treats the & as either a literal or a word-breaker, depending on the values on both sides of the &. Try the following examples:
DECLARE #Term NVARCHAR(100);
SET #Term = N'bob&sally'; -- 48 rows
--SET #Term = N'bob\&sally'; -- 48 rows
--SET #Term = N'r&f'; -- 4 rows
--SET #Term = N'r\&f'; -- 24 rows
SET #Term = N'FORMSOF(INFLECTIONAL,"' + #Term + '")';
SELECT * FROM sys.dm_fts_parser(#Term, 1033, 0, 0);
SELECT * FROM sys.dm_fts_parser(#Term, 1033, 0, 1);
SELECT * FROM sys.dm_fts_parser(#Term, 1033, NULL, 0);
SELECT * FROM sys.dm_fts_parser(#Term, 1033, NULL, 1);
The results for bob&sally and bob\&sally are the same, and in both cases bob and sally are separated and never combined into a single exact-match string.
The results between r&f and r\&f, however, are not the same. r&f is only ever treated as a single, exact-match string because r and f alone are not known words. On the other hand, adding in the back-slash separates the two letter since \ is a word-breaker, in which case you get both r and f.
Given that you stated in the Update that you have "data inconsistency, where one of the brands with the "&" in its name was modified not to have the "&", and the other one wasn't", I suspect that when you do not add in the \ character you get the brand that was not modified (since it is an exact match for the full term). But when you do add in the \ character, then you get the brand that was modified to have the & removed, since you are now searching on both pieces, each one matching part of that brand name.
I would fix the data to be consistent: update the brand names that had the & removed to put the ampersands back in. Then when people search using & without the extra \ added, it will be an exact match. This behavior will be consisted across the data, and will not require you adding code to circumvent the natural operation of FTS, which seems to be an error-prone approach.

Building dynamic query for Sql Server 2008 when table name contains " ' "

I need to fetch Table's TOP_PK, IDENT_CURRENT, IDENT_INCR, IDENT_SEED for which i am building dynamic query as below:
sGetSchemaCommand = String.Format("SELECT (SELECT TOP 1 [{0}] FROM [{1}]) AS TOP_PK, IDENT_CURRENT('[{1}]') AS CURRENT_IDENT, IDENT_INCR('[{1}]') AS IDENT_ICREMENT, IDENT_SEED('[{1}]') AS IDENT_SEED", pPrimaryKey, pTableName)
Here pPrimaryKey is name of Table's primary key column and pTableName is name of Table.
Now, i am facing problem when Table_Name contains " ' " character.(For Ex. KIN'1)
When i am using above logic and building query it would be as below:
SELECT (SELECT TOP 1 [ID] FROM [KIL'1]) AS TOP_PK, IDENT_CURRENT('[KIL'1]') AS CURRENT_IDENT, IDENT_INCR('[KIL'1]') AS IDENT_ICREMENT, IDENT_SEED('[KIL'1]') AS IDENT_SEED
Here, by executing above query i am getting error as below:
Incorrect syntax near '1'.
Unclosed quotation mark after the character string ') AS IDENT_SEED'.
So, can anyone please show me the best way to solve this problem?
Escape a single quote by doubling it: KIL'1 becomes KIL''1.
If a string already has adjacent single quotes, two becomes four, or four becomes eight... it can get a little hard to read, but it works :)
Using string methods from .NET, your statement could be:
sGetSchemaCommand = String.Format("SELECT (SELECT TOP 1 [{0}] FROM [{1}]) AS TOP_PK, IDENT_CURRENT('[{2}]') AS CURRENT_IDENT, IDENT_INCR('[{2}]') AS IDENT_ICREMENT, IDENT_SEED('[{2}]') AS IDENT_SEED", pPrimaryKey, pTableName, pTableName.Replace("'","''"))
EDIT:
Note that the string replace is now only on a new, third substitution string. (I've taken out the string replace for pPrimaryKey, and for the first occurrence of pTableName.) So now, single quotes are only doubled, when they will be within other single quotes.
You need to replace every single quote into two single quotes http://beyondrelational.com/modules/2/blogs/70/posts/10827/understanding-single-quotes.aspx

Incorrect syntax near ')', possible incorrect use of substring() or charindex()?

I'm trying to run an ADODB query on a SQL Server database instance of ProjectWise, using the query defined by the following string:
select
dms_audt.o_acttime as actionTime,
dms_stat.o_statename as state,
dms_doc.o_filename as filename,
dms_doc.o_projectno as project
from dms_audt
inner join
dms_stat
on dms_audt.o_numparam2=dms_stat.o_stateno
inner join dms_doc on dms_audt.objguid=dms_doc.o_docguid
where substring(dms_doc.o_filename,1,4)="abcd")
and charindex(dms_doc.o_filename,"efgh")=0
VBA is giving me a runtime error of:
Incorrect syntax near ')'
which makes me think that I'm either using substring() or charindex() incorrectly. I've received this error regardless of whether I wrap the abcd and efgh strings in single or double quotes. Any idea what I'm doing wrong here?
You have an extra bracket.
this > where substring(dms_doc.o_filename,1,4)="abcd")
and charindex(dms_doc.o_filename,"efgh")=0
needs to be:
where substring(dms_doc.o_filename,1,4)='abcd' and charindex(dms_doc.o_filename,'efgh')=0

Resources