Informix apostrophe SQL error - sql

I get [Informix][Informix ODBC Driver][Informix]A syntax error has occurred when running the query below. When I remove the double apostrophes the query executes successfully. Everything I can find by Googling tells me I'm doing the right thing. Seven years ago I used Informix without this sort of problem so I think I've forgotten something important!
insert into ct_repairs (ct_job_no,inh_job_no,reference,tab
,rec_date,rec_time,priority,start_dte,start_tme,app_date
,app_time,card_date,card_time,est_date_comp,est_time_comp
,act_date_comp,act_time_comp,exp_code,ct_notes,ct_status
) values (
2090
,335706
,'23026002003'
,'P'
,NULL
,''
,1
,"22/02/2010"
,'10:47'
,NULL
,''
,"22/02/2010"
,'11:14'
,NULL
,''
,NULL
,''
,'DTD'
,'**PLS NOTE PLANNED WRKS GOING ON ON ASCOT RD,IE ROOFS,RENDERERING,AND HIGH LEVEL CLOSE BOARD FENCES:SPOKE TO THE LADY AT NO 2 SHE DOESN''T NO ANYTHING ABOUT FENCE ISSUES,CALLED AT NO 4#6 ASCOT NO ACCESS TO EITHER PROPERTIES**:YOU YOU PLS SEND A EMAIL TO TREVOR ON PLANNED ASKING IF NO 2 ASCOT RD IS DOWN FOR A NEW CLOSED BOARDED FENCE,OR IS THAT THE PROBLEM NO 4 BEING PRIVATE THAT THEY HAVEN''T PUT ONE UP**'
,0
)

It would be helpful if you identified the version of ODBC you are using, and the version of IDS (IBM Informix Dynamic Server), and the platform where they are running.
When I copy'n'paste the code from the question into SQLCMD (equivalent to DB-Access) in a database without the table, I get the error:
SQL -206: The specified table (ct_repairs) is not in the database.
This indicates that the SQL is syntactically correct.
So, why are you seeing an error?
My first suspect for the guilty party is the long (400+) character string at the end. At one time (a while ago now, AFAICR) there was an upper bound of 255 on the length of a character string literal. If you are using an old enough version of the ODBC driver (or IDS), this could be a factor.
My second suspect is the occasional double-quoted date string. Informix is generally lax about whether you use single or double quotes around strings; this can be helpful. However, there is a way to make it pedantic like the SQL standard, requiring single quotes around strings and using double quotes only for 'delimited identifiers'. If the DELIMIDENT environment variable is set (perhaps via SETNET32 on Windows), the strict mode would be invoked, and when I do that in SQLCMD, I get:
SQL -201: A syntax error has occurred.
The third suspect is that the long column is a BYTE or TEXT (or possibly BLOB or CLOB) type, and there isn't a conversion from a string literal to that type. However, AFAIK, the ODBC driver jumps through hoops to deal with that problem, and the error would be different, probably something like:
SQL -617: A blob data type must be supplied within this context.
So, at the moment, I think the DELIMIDENT is well worth chasing - it is probably easily fixed (either by ensuring that dates are enclosed in single quotes or by unsetting DELIMIDENT). Failing that, try a shorter string and see whether that works.
But your basic understanding is correct - you are using doubled-up single quotes correctly.

Related

Why accents are not recognized in sqlplus

I have a subject table which has a theme field contains the following rows :
theme
-----
pays
économie
associée
And I have this basic query :
SELECT * FROM SUBJECT WHERE THEME='associée';
The query runs fine in Sql developer and returns the expected row to me.
On the other hand under Sqlplus it returns 0 lines to me (which is not normal).
I have the impression that the query does not recognize accented characters under sqlplus. I am thinking of an NLS_LANG problem but I do not know about it. Please help.
Thank you in advance.
Set your OS session's NLS_LANG variable to the value of, e.g., ENGLISH_AMERICA.AL32UTF8 and restart your SQL Developer. Retry afterwards.
If that didn't help, try also running your query as follows:
SELECT * FROM SUBJECT WHERE THEME = n'associée';
Notice the n before the string literal. That's a nvarchar2 string literal modifier. Depending on your DB charset/national charset settings you may need to explicitly state that the value you are querying for, is "national charset", not just a "regular charset".
If that didn't help, there's actually a multitude of additional variables that come into play when working with accented characters against an Oracle DB.
Explanation:
Your SQL Developer does recognize accents... provided that you have your Oracle DB session using character set compatible with your database character set. And your Oracle DB session's character set can be set either on OS level (via OS environment variable) or, possibly(!), in SQL Developer's options directly. Alas, the said multitude of other factors may include (though not exclusively):
your OS regional settings,
your OS Unicode support,
your Oracle client software's (SQL Developer) Unicode support,
your Java JDK/JRE's Unicode support,
your JDBC driver's Unicode support,
your other *DBC drivers' Unicode support, if there are any more in chain.
Sad thing is that the more interfaces you have between your keyboard and your Oracle database, the more likely is one of them to fiddle with your charset conversions badly.
So, let's just hope that the first two hints work for you, otherwise I can't help you (that easily).

Syntax error in INSERT INTO statement

I am trying to insert some information in an MS Access database.
In my database I have the following columns and types:
log_order - Autonumber (I need this to keep the order where inserted in the db),
userID - Text,
time - Text,
date_ - text,
message - Text.
My query:
command.CommandText = "INSERT INTO logs(userID, time, date_, message) VALUES ('"+verifiedUser+"', '"+msg_time+"', '"+msg_date+"', '"+msg+"')";
OleDbDataReader reader = command.ExecuteReader();
The error that I get:
System.Data.OleDb.OleDbException: 'Syntax error in INSERT INTO statement.'
I tried several posts but no post helped me. I believe there might be a problem with the autonumber column (log_order). Because of what I remember I don't have to include it in the query.
PS: I know I have to pass the values as parameters.
Thank you in advance
Probably one of your variables (msg?) contains an apostrophe
The way you've written your SQL is a massive security risk. Please immediately look up "parameterized queries" and never, ever, ever write an sql like this again (where you use string concatenation to tack the values into the query). Your code has a proliferation of issues and using parameterized queries will solve all of them; they aren't difficult to write
It seems your data in some of the variables passed in INSERT may be causing this error. Try debugging the value in command.CommandText before executing it.
If any of the variables have a single quote they must be escaped...
Ref: How do I escape a single quote in SQL Server?
Also brush up on SQL Injection Ref: SQL Injection
I totally agree with all that has been said, but to answer your question directly, I am pretty sure you will need to put square brackets around your field names. OleDb tends not to like special characters and could well be having a problem for example with date_ ; sending [date_] instead should get round the issue.
It will not like time either. Same solution
Addendum on SQL Injection
As an aside, in fact calling Access through OleDb is relatively protected from SQL Injection. This is because any attempt to execute multiple instructions in one command fails. (You get an incorrect formatted string error). So whilst you could argue that what you are doing is safe, it is not for other db providers. The sooner you get into good habits, the less likely you will be to introduce a vulnerability in a case where it could be dangerous. If it seems like you are getting a stream of abuse, it is just because everyone here wants to keep the net safe.

SQL statement against Access 2010 DB not working with ODBC

I'm attempting to run a simple statement against an Access DB to find records.
Data validation in the records was horrible, and I cannot sanitize it. Meaning, it must be preserved as is.
I need to be able to search against a string with white space and hyphen characters removed. The following statement will work in Access 2010 direct:
select * from dummy where Replace(Replace([data1],' ',''),'-','') = 'ABCD1234';
Running it from an ODBC connection via PHP will not. It produces the following error:
SQL error: [Microsoft][ODBC Microsoft Access Driver] Undefined function 'Replace' in expression., SQL state 37000 in SQLExecDirect
Creating a query in the database that runs the function and attempting to search its values indirectly causes the same error:
select * from dummy_indirect where Expr1 = 'ABCD1234';
I've attempted to use both ODBC drivers present. ODBCJR32.dll (03/22/2010) and ACEODBC.dll (02/18/2007). To my knowledge these should be current as it was installed with the full Access 2010 and Access 2010 Database Engine.
Any ideas on how to work around this error and achieve the same effect are welcome. Please note, that I cannot alter the database in way, shape, or form. That indirect query was created in another mdb file that has the original tables linked from the original DB.
* Update *
OleDB did not really affect anything.
$dsn= "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\dummy.mdb;";
I'm not attempting to use it as a web backend either. I'm not a sadomasochist.
There is a legacy system that I must support that does use Access as a backend. Data gets populated there from other old systems that I must integrate into more modern systems. Hence, the creation of an API with Apache/PHP that is running on the server supporting the legacy system.
I need to be able to search a table that has an alphanumeric case identifier to get a numeric identifier that is unique and tied to a generator (Autonumber in access). Users have been using it a trash box for years (inconsistent data entry with sporadic notations) so the only solution I have is to strip everything except alphanumeric out of both the field value and the search value and attempt to perform a LIKE comparison against it.
If not replace() which is access supported, what ODBC compatible functions exist that I can use do the same kind of comparison?
Just to recap, the Access db engine will not recognize the Replace() function unless your query is run from within an Access application session. Any attempt from outside Access will trigger that "Undefined function" error message. You can't avoid the error by switching from ODBC to OleDb as the connection method. And you also can't trick the engine into using Replace() by hiding it in separate query (in the same or another Access db) and using that query as the data source for your main query.
This behavior is determined by Access' sandbox mode. That linked page includes a list of functions which are available in the default sandbox mode. That page also describes how you can alter the sandbox mode. If you absolutely must have Replace() available for your query, perhaps the lowest setting (0) would allow it. However, I'm not recommending you do that. I've never done it myself, so don't know anything about the consequences.
As for alternatives for Replace(), it would help to know about the variability in the values you're searching. If the space or dash characters appear in only one or a few consistent positions, you could do a pattern match with a Like expression. For example, if the search field values consist of 4 letters, an optional space or dash, followed by 4 digits, a WHERE clause like this should work for the variations of "ABCD1234":
SELECT * FROM dummy
WHERE
data1 = 'ABCD1234'
OR data1 Like 'ABCD[- ]1234';
Another possibility is to compare against a list of values:
SELECT * FROM dummy
WHERE
data1 IN ('ABCD1234','ABCD 1234','ABCD-1234');
However if your search field values can include any number of spaces or dashes at any position within the string, that approach is no good. And I would look real hard for some way to make the query task easier:
You can't clean the stored values because you're prohibited from altering the original Access db in any way. Perhaps you could create a new Access db, import the data, and clean that instead.
Set up the original Access db as a linked server in SQL Server and build your query to take advantage of SQL Server features.
Surrender. :-( Pull in a larger data set to your PHP client code, and evaluate which rows to use vs. which to ignore.
I'm not sure you can do this with ODBC and your constraints. The MS Access driver is limited (by design; MS wants you to use SQL Server for back ends).
Can you use OLEDB? that might be an option.

Issues with Chr(0) in SQL INSERT script

We currently use the SQL Publishing Wizard to back up our database schemas and data, however we have some database tables with hashed passwords that contain the null character (chr(0)). When SQL Publishing Wizard generates the insert data scripts, the null character causes errors when we try and run the resulting SQL - it appears to ignore ALL TEXT after the first instance of this character in a script. We recently tried out RedGate SQL Compare, and found that it has the same issue with this character. I have confirmed it is ascii character code 0 by running the ascii() sql function against the offending record.
A sample of the error we are getting is:
Unclosed quotation mark after the character string '??`????{??0???
The fun part is, I can't really paste a sample Insert statement because of course everything that appears after the CHR(0) is being omitted when pasting!
Change the definition of the column to VARBINARY. The data you store in there doesn't seem to be an appropiate VARCHAR to start with.
This will ripple through the code that uses the column as you'll get a byte[] CLR tpe back in the client, and you should change your insert/update code accordingly. But after all, a passowrd hash is a byte[], not a string.

Trapping Exception using TSQLQuery & params

I am getting a "SQL Server Error: arithmetic exception, numeric overflow, or string truncation" error
here is the code below
AQuery:= TSQLQuery.Create(nil);
with AQuery do
begin
SQLConnection:- AConnection;
SQL.Text:= 'Insert into.....';
ParamByName('...').asString:= 'PCT';
.
.
.
try
ExecSQL;
finally
AQuery.Free;
end;
end;
I have alot of ParamByName lines, and I can't figure out which one is throwing the exception. I just know its thrown on the ExecSQL line. How can i tell which paramByName is causing the error?
When you have the metadata of the table, check the maximum length of string fields. When debugging, check the length of the strings you feed the parambynames. Also check the type of numeric fields, and make sure you don't exceed a maximum value. (I had this problem once with a string which length exceeded the varchars length in the table, and had this problem with a smallint databasefield that I tried to set to a too high value)
Get the SQL text after param substitution and run it as a query in SQL Server management studio.
You'll be able to debug it from there.
You are trying to insert a string value into a field that is not big enough to hold the value. Check the length of the values you are inserting against the length of the field in the table.
As others have said, it's almost certainly that you are pushing too-large a string into one of your fields. It could also happen with numeric values but it's most likely to be a string.
I'd suggest you temporarily alter each of your ParamByName('').AsString:=blah lines with a text constant, eg;
ParamByName('surname').AsString:='Smith';
ParamByName('firstname').AsString:='John';
etc, and see if you get an error. If it goes through without an error, then your problem is most likely to be that one of your string parameters is too long. Check your table schema and debug the actual strings you are putting into the parameters.
Depending on how much access (and experience) you have with this, you might find it more helpful to turn on the SQL Server logging such that you can see your queries (and the contents of those parameters) when the get processed by the SQL server. This will show you exactly what string and numeric values are actually being given to the server.
Which version/edition of SQL Server are you using?