Postgres SQL operator does not exist; character = integer; - postgresql

I am do replicating of two database (SQL Server 2000 and PostgreSQL). I use http://blog.hagander.net/archives/103-Replicating-from-MS-SQL-Server-to-PostgreSQL.html for this. Then I do last step the
ERROR: operator does not exist: character = integer; Error executing the query
appeared. I use the PostgreSQL 8.4.6 for that and ODBC drivers (all psqlodbc_08_04_0100.zip, psqlodbc_08_04_0200.zip) from here i also try to delete and install version that Synaptic called 9.0.2-1 and update odbc drivers i try (psqlodbc_09_00_0100.zip, psqlodbc_09_00_0101.zip, psqlodbc_09_00_0200.zip) it also return that error. The query launched from delphi where i use only System DSN runs normally

You need to fix your SQL statement.
I bet you have something like
WHERE character_column = 1
and you need to change that to
WHERE character_column = '1'

use single quote 'your_value' for non numeric data and double quote for column name and never the opposite.
select status, sum(amount) as sum from "sales" where ("date" <= '2017-04-30 23:59:59' and "customer_id" = 1) and "sales"."deleted_at" is null group by "status"

Related

Error using regular expressions in DB2 - wrong syntax?

i tried to run this query in DB2 ( which includes regex ). I am getting the following error. Can someone help?
Here is the query:
SELECT COUNT(*) FROM TABLE WHERE REGEXP_LIKE(TRIM(FIELD), '[^[:digit:]]')
Support for BOOLEAN data type is new in Db2 11.1.1.1 (i.e. the first Mod Pack + Fix pack for Db2 11.1). If you are only on Db2 11.1.0.0, then you will need to explicitly test the result of your regex function.
SELECT COUNT(*) FROM TABLE
WHERE REGEXP_LIKE(TRIM(FIELD), '[^[:digit:]]') = 1;

Dreamfactory: Database connection to Postgres

First I set up the dream factory by "Bitnami Installer for Windows". Following to https://github.com/dreamfactorysoftware/dsp-core/wiki/Install-Microsoft-Windows
Then I follow this add-a-rest-api-to-any-sql-db-in-minutes to add Services to my Remote Postgres Database.
On the "API Docs" tab, it is success to call the GET /db operation. ( getTables() - List all table names).
I got the following error when trying to call GET /db/{table_name} operation ( getRecordsByFilter() - Retrieve one or more records by using a filter).
Please help
[app][ERROR ] CDbCommand::fetchAll() failed: SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "field_name"
LINE 1: SELECT k.column_name field_name
^. The SQL statement executed was: SELECT k.column_name field_name
FROM "information_schema"."key_column_usage" k
LEFT JOIN "information_schema"."table_constraints" c
ON k.table_name = c.table_name
AND k.constraint_name = c.constraint_name
WHERE c.constraint_type ='PRIMARY KEY'
AND k.table_name = :table
AND k.table_schema = :schema.
Please check the version of PostgreSQL you are connecting to. It turns out that omission of as keyword is supported starting from 8.4.
Here's a quote from 8.4 release notes section E.23.3.3. Queries:
Allow AS to be optional when specifying a SELECT (or RETURNING) column
output label (Hiroshi Saito)
This works so long as the column label is not any PostgreSQL keyword;
otherwise AS is still needed.
Therefore SELECT k.column_name field_name is not valid for 8.3 and below, but SELECT k.column_name AS field_name would work.
If PostgreSQL version is the cause of your problem you have several options:
update the database to 8.4 and above;
patch the Dreamfactory codebase yourself to work around this problem;
raise a ticket in Dreamfactory's bug tracker and wait them to fix it for you.

Convert differences between SQL Server 2008 R2 and 2012

I've got an issue while executing a SQL statement in SQL Server 2012 while it's perfectly working in a SQL Server 2008 R2...
The error message is :
Msg 8114, Level 16, State 5, Line 1
Error converting data type varchar
to numeric.
I want to execute this SQL Select statement :
Select
count(*)
from IMPORTBM
inner join ATTRIBUTE on ATT_ATTRIBUTE_ID = IMP_ATTRIBUTE_ID
where IMP_LOCATION_ID = 2
AND IMP_SERIAL_ID = 310001
AND IMP_VERSION_ID = 1
AND (
(ATT_ATTRIBUTE = 'PS_APISizing'
AND IMP_VALUE = 'C')
OR
(ATT_ATTRIBUTE = 'DTD'
AND ISNUMERIC(IMP_VALUE) = 1
AND CAST( IMP_VALUE as NUMERIC(38,19)) <= 0.469)
OR
(ATT_ATTRIBUTE = 'IOD'
AND ISNUMERIC(IMP_VALUE) = 1
AND CAST( IMP_VALUE as NUMERIC(38,19)) BETWEEN 3.684 AND 4.225)
)
Could you help me finding out why it's not working with SQL Server 2012 please ?
The problem is that conditions are not always evaluated in the order you place them. This means that Cast(IMP_VALUE as numeric(38, 19)) can fail when it is a non-numeric value, if the query execution plan happens to evaluate this before the IsNumeric(IMP_VALUE) = 1.
This is not determined by how many clauses there are or what version of SQL Server you're running--those are only coincidences. The problem is exactly as I described. The fact that you get different results with different queries is due to different queries, or different servers, using different execution plans.
The cure is to make sure that all conditions will not throw an error, no matter what order they are executed in.
For all versions of SQL Server, you can do this:
Convert(
numeric(38,19),
CASE WHEN IsNumeric(IMP_VALUE) = 1 THEN IMP_VALUE ELSE NULL END
) <= 0.469
Or, in SQL Server 2012 and up, you can use Try_Convert:
Try_Convert(numeric(38,19), IMP_VALUE) <= 0.469
If your server complains that this is not a built-in function name, then it is likely that your database was upgraded from a prior version and you need to alter the database compatibility level. Note that doing this could have some other effects in the system that you need to consider, so study up on it first, and try it out in a non-production system before doing it in production (or do it during a non-critical period and set the compatibility level back if you run into any issues). The danger is not that any damage will occur, but that query results could be different or errors could occur (different ordering of query or stored procedure results being a more common occurrence).
ALTER DATABASE database_name
SET COMPATIBILITY_LEVEL = 110; -- SQL Server 2012
What is the definition of the table? (IMP_VALUE at least). Why not store numeric in the 1st place...
2008 and 2012 query plan probably differ and does not handle the parameter and condition in the same order.
With SQL Server 2012 (compatibility level 110) you can try to replace the 2 cast:
AND ISNUMERIC(IMP_VALUE) = 1
AND CAST( IMP_VALUE as NUMERIC(38,19)) <= 0.469)
by
AND TRY_CONVERT(NUMERIC(38,19), IMP_VALUE) <= 0.469
AND TRY_CONVERT(NUMERIC(38,19), IMP_VALUE) BETWEEN 3.684 AND 4.225
It returns NULL without error when it cannot convert it.

DB2 - If table is empty for date X, insert, else go on

--DB2 version 10 on AIX
I have a stored procedure, which I need to update. And want to check if there is data for a certain date. If data exists, go on, else run insert and then go on.
IF (SELECT COUNT(*)
FROM SCHEMA1.TABLE1_STEP1
WHERE XDATE = '9/27/2014' < 1)
THEN (INSERT INTO SCHEMA1.TABLE1_STEP1 (SELECT * FROM SCHEMA2.TABLE2 FETCH FIRST 2 ROWS ONLY))
END IF;
This errors-out.
DB2 Database Error: ERROR [42601] [IBM][DB2/AIX64] SQL0104N An unexpected token "(" was found following "/2014') < 1) THEN". Expected tokens may include: "". SQLSTATE=42601
Any thoughts on what's wrong?
I'm guessing you probably want the less than sign outside of the parenthesis...
However, as an aside, you can also do this kind of statement without an IF (although, I don't have an AIX DB2 available to check for sure. It worked on DB2 for z/OS and LUW, however):
INSERT INTO SCHEMA1.TABLE1_STEP1
SELECT *
FROM SCHEMA2.TABLE2
WHERE NOT EXISTS (
SELECT *
FROM SCHEMA1.TABLE1_STEP1
WHERE XDATE = '9/27/2014'
)
FETCH FIRST 2 ROWS ONLY
Also, you're not providing an ORDER BY on the SCHEMA2.TABLE2 select, so your results could come back in any order (whatever is "easiest" for the database engine)... order is not guaranteed unless you provide the ORDER BY statement.

PostgreSQL execute statement conditionally by server version

I'm currently writing some installer script that fires SQL files against different database types depending on the system's configuration (the webapplication supports multiple database server like MySQL, MSSQL and PostgreSQL).
One of those types is PostgreSQL. I'm not fluent with it and I would like to know if it's possible to make a statement into a define/populate SQL file that makes an SQL query conditional to a specific PostgreSQL server version.
How to make an SQL statement conditionally in plain PGSQL so that it is only executed in version 9? The command is:
ALTER DATABASE dbname SET bytea_output='escape';
The version check is to compare the version with 9.
Postgres does have version() function, however there is no major_vesion(). Assuming that output string always includes version number as number(s).number(s).number(s) you could write your own wrapper as:
CREATE OR REPLACE FUNCTION major_version() RETURNS smallint
AS $BODY$
SELECT substring(version() from $$(\d+)\.\d+\.\d+$$)::smallint;
$BODY$ LANGUAGE SQL;
Example:
=> Select major_version();
major_version
---------------
9
(1 row)
However real issue here is that AFAIK you can't execute your commands conditionally in "pure" SQL and best what you can do is to write some stored function like this:
CREATE OR REPLACE FUNCTION conditionalInvoke() RETURNS void
AS $BODY$
BEGIN
IF major_version() = 9 THEN
ALTER DATABASE postgres SET bytea_output='escape';
END IF;
RETURN;
END;
$BODY$ LANGUAGE plpgsql;
I think that you should rather use some scripting language and generate appropriate SQL with it.
Or you could just use
select setting from pg_settings where name = 'server_version'
Or
select setting from pg_settings where name = 'server_version_num'
If you need major version only
select Substr(setting, 1, 1) from pg_settings where name = 'server_version_num'
or
select Substr(setting, 1, strpos(setting, '.')-1) from pg_settings where name = 'server_version'
if you want it to be compatible with two digit versions.
Maybe you could make things dependent on the output of
select version();
(probably you'll have to trim and substring that a bit)
BTW (some) DDL statements may not be issued from within functions; maybe you'll have to escape to shell-programming and here-documents.