Pgsql error: You might need to add explicit type casts - postgresql

My website is just working fine til i deployed it to heroku and the problem is heroku uses pgsql and I'm using mysql and laravel framework.
my query is
$patient = Patient::where('patient_address', 'ILIKE' ,'%' . $request->input)->where('patient_sex', 'ILIKE' ,'%' . $request->gender)->whereHas('users', function($q) use($vaccine_id){
$q->where('vaccine_id','ILIKE','%' . $vaccine_id);
})->get();
here's what I'm getting when I deploy it to heroku
SQLSTATE[42883]: Undefined function: 7 ERROR: operator does not exist: integer ~~* unknown
LINE 1: ...ient_id" = "patients"."PatientID" and "vaccine_id" ILIKE $3)
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. (SQL: select * from "patients" where "patient_address" ILIKE %San Francisco and "patient_sex" ILIKE % and exists (select * from "vaccines" inner join "immunizations" on "vaccines"."VaccineID" = "immunizations"."vaccine_id" where "immunizations"."patient_id" = "patients"."PatientID" and "vaccine_id" ILIKE %))
I have tried using cast like CAST(vaccine_id AS VARCHAR) and I' not getting the error but it doesnt return any result.

The problem is here:
$q->where('vaccine_id','ILIKE','%' . $vaccine_id)
looks like vaccine_id is integer, and you can not use operator ILIKE to integer. Try just '='
If you want to use LIKE, ILIKE or other text operator you must cast your data to text. In SQL it must looks like:
WHERE "vaccine_id"::text ILIKE val
instead
WHERE "vaccine_id" ILIKE val

You could do this:
$q->where('cast(vaccine_id AS VARCHAR)','LIKE','%' . $vaccine_id)
OR
$q->where('cast(vaccine_id AS TEXT)','LIKE','%' . $vaccine_id)

Related

DB2 Assign result of with clause to variable

I am using DB2 LUW and want to a assign a result of a With clause to a variable in a stored procedure.
I got the exception
{0:0} An unexpected token "AS" was found following "l = (WITH BASE". Expected tokens may include: "JOIN".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.28.11
Is it possible to assign the result on this way or should I have to solve it with a cursor?
DECLARE result CLOB(8M);
SET result = (WITH BASE AS (
xxx
)
SELECT JSON_ARRAY (select json_objects FROM ITEMS format json) FROM SYSIBM.SYSDUMMY1);
Use instead the syntax style:
with ctename AS ( ... ) SELECT ... INTO ... FROM ctename;

Postgresql - How to make NOT LIKE + SELECT statement, comparing two columns between tables

Hit a bit of a brickwall here, I haven't found anything that seems to work.
SELECT *
FROM glsltransaction gls
INNER JOIN glhistory h ON gls.sltrxid = h.schedxrefid
INNER JOIN apvendor ap ON ap.vendorid = gls.acctid
INNER JOIN glchartofaccounts coa USING (acctdeptid)
WHERE h.description <> gls.description
AND h.description not like || ap.name || '%'
AND gls.description <> ''
This line here AND h.description not like || ap.name || '%' is what i'm having issues with.
I get the following error when trying to run that statement above:
'Error occurred in running query from editor : ERROR: operator does not exist: || text Hint: No operator matches the given name and argument type. You might need to add an explicit type cast. Position: 563'
I'm effectively wanting it to function like a.column not like b.column%
Any help will be greatly appreciated, thanks!

Postgresql SQLSTATE[42P18]: Indeterminate datatype with PDO and CONCAT

I'm having issues with CONCAT() when used on a WHERE, in PDO.
The code:
<?php
require_once('config.php');
$fdate = '01/01/2010';
$tdate = '31/12/2030';
$identification = '';
$count = "SELECT count(*) as total FROM ( select time_id from doc_sent WHERE date >= :fdate AND date <= :tdate AND identification LIKE concat('%',:identification,'%') ) x;";
//$count = "SELECT count(*) as total FROM ( select time_id from doc_sent WHERE date >= :fdate AND date <= :tdate ) x;";
$stmt_count_row_main_table = $pdo->prepare($count);
$stmt_count_row_main_table->execute(['fdate' => $fdate, 'tdate' => $tdate, 'identification' => $identification]);
//$stmt_count_row_main_table->execute(['fdate' => $fdate, 'tdate' => $tdate]);
$count_row_main_table = $stmt_count_row_main_table->fetch();
print_r( $count_row_main_table);
?>
The code works when the 'identification' part is commented.
When I'm trying to use CONCAT(), it doesn't.
I tried many "version" of CONCAT() (and read many other questions, like this one: How do I create a PDO parameterized query with a LIKE statement? ) but I am always referring to the main documentation:
https://www.postgresql.org/docs/9.1/static/functions-string.html
Which say:
concat('abcde', 2, NULL, 22) --> abcde222
The FULL error when I use CONCAT() is:
PHP Fatal error: Uncaught PDOException: SQLSTATE[42P18]: Indeterminate datatype: 7 ERROR: could not determine data type of parameter $3 in /var/www/pdo-reporter/show.php:17\nStack trace:\n#0 /var/www/pdo-reporter/show.php(17): PDOStatement->execute(Array)\n#1 {main}\n thrown in /var/www/pdo-reporter/show.php on line 17
What's wrong with my code?
CONCAT is a function that takes a VARIADIC argument list, which means that internally postgres will convert them into an array of the same type.
postgres=# \df concat
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+--------+------------------+---------------------+------
pg_catalog | concat | text | VARIADIC "any" | func
When trying to resolve the input type to a single type, the SQL parser fails. It can be reproduced in this simpler form:
postgres=# PREPARE p AS select concat('A', $1);
ERROR: could not determine data type of parameter $1
The parser can't figure out the datatype of $1 so it errs on the side of caution.
One easy solution is to cast the parameter as text:
postgres=# PREPARE p AS select concat($1::text);
PREPARE
or with the CAST operator:
postgres=# PREPARE p AS select concat(cast($1 as text));
PREPARE
I haven't tested with PDO but presumably it would work (given how it deals with parameters to produce prepared statements) to change the query to:
"...identification LIKE '%' || :identification || '::text%'..."
or use the '||' operator instead of concat in the query:
identification LIKE '%' || :identification || '%'
EDIT: BTW if you want to find that a parameter :X is a substring of identification, this clause is more secure: strpos(identification, :X) > 0, because :X may contain '%' or '_' without causing any side-effect in the match, contrary to what happens with LIKE.

SQL Command failed with: ERROR: operator does not exist: character varying?

i am trying to get values from database by using following query
SELECT Distinct org.name AS org, sto.ad_org_id AS wh_nearstoredetails_id, sum(sto.qtyonhand) AS qty, pro.name AS product
FROM ad_org org, m_storage_detail sto, m_product pro
WHERE sto.ad_org_id::text = org.ad_org_id::text
AND (sto.m_locator_id::text IN ( select cast(m_locator.m_locator_id as text)
from m_locator,m_warehouse
where m_warehouse.isactive = cast('Y' as varchar)
and m_warehouse.em_ai_warehouseparent::text not like cast('' as text)
and m_warehouse.m_warehouse_id::text = m_locator.m_warehouse_id::text
and m_locator.isdefault = cast('Y' as varchar)))
AND sto.m_product_id::text = pro.m_product_id::text
AND sto.qtyonhand >= cast(1 as numeric)
AND sto.ad_org_id::text IN ( SELECT cast(m_warehouse.ad_org_id as text)
FROM m_warehouse
WHERE m_warehouse.em_ai_warehouseparent::text not like cast('' as text))
GROUP BY org.name,sto.ad_org_id,pro.name
ORDER BY org.name, pro.name;
after creating this i also created a class to call this query and get data but when i deploy my project i am getting following error
WARN - SQL Command failed with: ERROR: operator does not exist: character varying !
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
please help to solve this issue.
i finally found the mistake what i made.
the problem in the above query is i'm trying to make type cast of null value
now i changed the condition to check 'is not null' than "not like ''"
and even i don't need to add cast operation it's useless.
anyways thanks for you response. :)

Escaping hstore contains operators in a JDBC Prepared statement

I am using PostgreSQL 9.1.4 with hstore and the PostgreSQL JDBC driver (9.1-901.jdbc4).
I am trying to use the contains operators (?, ?&, ?|) in a PreparedStatement, however the ? character is parsed as a variable placeholder. Can this character be escaped to send the correct operator in the query?
An example:
PreparedStatement stmt = conn.prepareStatement("SELECT a, b FROM table1 WHERE c ? 'foo' AND d = ?");
stmt.setInt(1, dValue);
stmt.executeQuery();
In this form the following example would raise an exception:
org.postgresql.util.PSQLException: No value specified for parameter 2.
Update:
After investigating the query parser in the pgjdbc driver this snippet seems to indicate that it is not possible to escape the ? character. The questions that remain are:
Is there anything in the JDBC spec which allows a ? to be escaped and be anything other than a parameter placeholder?
Is there any better work around for this issue than just using plain Statements with variables manually inserted into the query string?
Effectively, it looks like the java SQL parser is not hstore compliant.
But since the syntax c ? 'foo' is equivalent to exist(c, 'foo'), you can easily workaround this problem. Have a look at the following page to see what the verbose operators for hstore are.
Postgres hstore documentation
There is a discussion about this issue on pgsql-hackers mailing list: http://grokbase.com/t/postgresql/pgsql-hackers/1325c6ys9n/alias-hstores-to-so-that-it-works-with-jdbc
For now I like most this workaround which also supports indexes:
CREATE FUNCTION exist_inline (hstore, text) RETURNS bool AS $$ SELECT $1 ? $2; $$ LANGUAGE sql;
You can use this query to find the function backing an operator in PostgreSQL like this. In your example:
SELECT
oprname,
oprcode || '(' || format_type(oprleft, NULL::integer) || ', '
|| format_type(oprright, NULL::integer) || ')' AS function
FROM pg_operator
WHERE oprname LIKE '?%'
AND (SELECT oid FROM pg_type WHERE typname = 'hstore') IN (oprleft, oprright);
This produces:
|oprname|function |
|-------|--------------------------|
|? |exist(hstore, text) |
|?| |exists_any(hstore, text[])|
|?& |exists_all(hstore, text[])|
See also a related question about using JSON operators containing ?. Note that the function usage may not profit from the same indexing capability when using a GIN index on your HSTORE column.
If you'd like to add multiple key-value pairs using PreparedStatement then you can do:
PreparedStatement ps = c.prepareStatement(
"insert into xyz(id, data) values(?, hstore(?, ?))");
ps.setLong(1, 23456L);
ps.setArray(2, c.createArrayOf("text", new String[]{"name", "city"}));
ps.setArray(3, c.createArrayOf("text", new String[]{"Duke", "Valley"}));
This will insert: 23456, 'name=>Duke, city=>Valley'