Invalid input syntax for integer but type is date? - postgresql

I'm trying to use a query to get date type value but it doesn't work...
tables:
Create table Clients1(
login char(30) primary key,
password varchar(30),
date_ad date,
name_c varchar(30),
adress varchar(30),
card_c varchar(30)
);
Create table clients_pay(
payment_ID char(15) primary key,
login char(15)
);
The following error appears:
22P02: invalid input syntax for integer: "2019/12/02"
My query is as follows:
SELECT DISTINCT login, COUNT(payment_ID) AS p
FROM Clients1
NATURAL INNER JOIN Payments1
NATURAL INNER JOIN clients_pay
GROUP BY login
HAVING COUNT(payment_ID) >='2019/12/02';
Since it's type date why it appears as integer?
I'm trying to see which clients can use service at date 2019/12/02?
(They can if payed)
Thank you

It looks like you want to have a WHERE clause limiting the payment_ids returned by a date, such as:
SELECT login, COUNT(payment_ID) AS p
FROM clients1
INNER JOIN clients_pay
ON clients_pay.login = Clients1.login
WHERE date_ad >='2019/12/02'
GROUP BY login ;
I also made some assumptions about the intention of your query and your data model, please edit your question to clarify those things if this doesn't meet your needs. Also note, Postgres identifiers are coerced to lowercase by default, unless you specify the casing by putting double quotes around the identifier during object creation. That practice is highly discouraged, though.

Related

PostgreSQL how to identify if values need to be quoted

I am trying to write a function that will dynamically create the sql statement, but I am facing problems with typecasts so, how can I identify using the type of field if it needs to be quoted
-- using this I can recover the types of each field
-- but I do not have a simple way to express that for a specific type it need
-- to quote
create table test (
id serial not null,
employee_name text,
salary decimal(12,2),
hire_date date,
active boolean
);
select column_name,data_type, null as need_to_be_quoted
from information_schema.columns
where table_name = 'table_name';
column type need to be quoted (this is a missing information)
-------------------------------------
id integer false
employee_name text true
salary decimal false
hire_date date true
active boolean false
quote_ident docs says:
Return the given string suitably quoted to be used as an identifier in an SQL statement string. Quotes are added only if necessary
But it is not what I was expecting:
insert into test (employee_name, salary, hire_date, active)
values (quote_identy('John Doe'), quote_identy(100000), quote_identy(current_date), quote_identy(true));
This is kind of necessary because I am trying to generate the statement string dinamically.
I have values to be inserted in some table, I can discover the type of each value, but to generated the insert string statement, I should know if a specific value type should be quoted or not for example
text: type should be quoted in the string statement
boolean: should not be quoted
numeric: should not be quoted
date: should be quoted
Don't quote. Quoting adds complexity and if you don't get it just right it has syntax and security issues.
Instead use bind parameters. The details depend on what database library you're working with, but the basic idea is always the same. First prepare the statement with placeholders for your values. Then execute it passing in the values. The database takes care of putting the values into the statement. You can execute the same prepared statement multiple times optimizing your coding and database calls.
Here's how you'd do it in PL/pgSQL with EXECUTE. The linked documentation has lots of information about safely executing dynamic queries.
do $$
begin
execute '
insert into test (employee_name, salary, hire_date, active)
values ($1, $2, $3, $4)
' using 'John Doe', 100000, current_date, true;
end;
$$;
Furthermore, while writing a SQL builder is a good exercise, it's also very complicated and very easy to get subtly wrong. There are plenty of libraries which will build SQL for you.
Here's your statement using PHP's Laravel.
DB::table('test')->insert([
'employee_name' => 'John Doe',
'salary' => 100000,
'hire_date' => current_date,
'active' => true
);
If you're curious about how SQL builders work, you can dig inside Laravel for ideas. Writing one in PL/pgSQL is ambitious, but I don't know of one that exists. Good luck!

what is the reasoning behind this 70-761 exam dump question

I would like to understand question about conversion:
exam dump I'm working with has this question at least three times with 3 different solutions you approve or don't approve of note that RegistrationNumber is defined as varchar(5) :
You run the following query:
SELECT UserId FROM tblVehicleRegistration
WHERE RegistrationNumber = 20012
AND RegistrationDate > '2016-01-01'
The query output window displays the following error message: “Conversion failed when converting the varchar value ‘AB012’ to data type int.”
You need to resolve the error.
Solution: You modify the Transact-SQL statement as follows:
SELECT UserId FROM tblVehicleRegistration
WHERE RegistrationNumber = '20012'
AND RegistrationDate > '2016-01-01'
answer says this does not work
I would think the test is incorrect. Here is a simplified example:
declare #tblVehicleRegistration table (RegistrationNumber varchar(5))
insert into #tblVehicleRegistration(RegistrationNumber) VALUES('AB012')
SELECT * FROM #tblVehicleRegistration WHERE RegistrationNumber = 20012 --Fails as expected
SELECT * FROM #tblVehicleRegistration WHERE RegistrationNumber = '20012' --works as expected
SQL Server will do a convertion in order to compare 'AB012' and 20012. If you check this link Data type precedence you will see that type varchar, wich is low precedence, needs to be converted to int, wich is high precedence, in order to make a comparison.
I created a table and tried hands-on. It worked properly after casting or changing the integer value to a string with quotation marks.

SQL WHERE clause not functional with string

I am trying to run a query that has a where clause with a string from a column of type VARCHAR(50) through PHP, yet for some reason it does not work in either PHP or MySQLWorkbench. My database looks like:
Database Picture:
The table title is 'paranoia' where the column 'codename' is VARCHAR(50) and 'target' is VARCHAR(50). The query I am trying to run takes the form, when searching for a codename entry clearly named '13Brownie' with no spaces, as follows:
UPDATE paranoia SET target='sd' WHERE codename='13Brownie'
Yet for some reason passing a string to the argument for codename is ineffective. The WHERE clause works when I do codename=7 or codename=3 and returns those respective integer codenames, and I can do codename=0 to get all the other lettered codenames. The string input works in neither MySQLWorkbench or the PHP script I will be using to update such selected rows, but again the integer input does.
It seems like the WHERE clause is only taking the integer values of my string input or the column is actually made up of the integer values of each entry, but the column codename is clearly defined as VARCHAR(50). I have been searching for hours but to no avail.
It is likely that there are white-space characters in the data. Things to try:
SELECT * FROM paranoia WHERE codename like '13%'
SELECT * FROM paranoia WHERE codename = '13Brownie '
SELECT codename, LEN(codename) FROM paranoia
VARCHAR(10) is a valid type to accept a string of at most 10 characters. I think this can possibly happen because of a foreign key constraint enforced with another table. check if you have this constraint using the "relation view" if you are on phpmyadmin.

i am getting an error" not valid month"

create table Department
(Dname varchar(255) NOT NULL, Dnumber int NOT NULL PRIMARY KEY, Mgr_SSN char(9) NOT NULL, Mgr_start_Date DATE);
insert into Department values('HR', '1', '11001', '2012-04-05 10:15:00');
I am getting the error "not valid month".
Should we define date format when we create the table?
I am using Oracle11g.
When you have a DATE column, you should always insert a DATE, not a VARCHAR2. Relying on implicit casting to correctly convert the string is a bad idea-- it is very easy for different sessions to have different NLS settings and, thus, to do the implicit conversion differently (either resulting in a different DATE or an error). The easiest way to do that is to use the to_date function.
insert into Department( dname,
dnumber,
mgr_ssn,
mgr_start_date )
values('HR',
1,
'11001',
to_date( '2012-04-05 10:15:00', 'yyyy-mm-dd hh24:mi:ss') );
I also modified the statement to list the columns, which is generally a good practice since it ensures that you don't have to look up the physical order of columns in the table every time and since it allows the INSERT statement to work in the future if you add new columns to the table. Since dnumber is a NUMBER, I also changed the INSERT statement to insert a number rather than inserting a string (again, don't rely on implicit conversion if there is no need to do so). I did not correct the apparent bug that you have a CHAR(9) column representing a social security number for which you are inserting a 5 character string.

Casting character varying field into a date

I have two tables,
details
id integer primary key
onsetdate Date
questionnaires
id integer primary key
patient_id integer foreign key
questdate Character Varying
Is it possible to make a SELECT statement that performs a JOIN on these two tables, ordering by the earliest date taken from a comparision of onsetdate and questdate (is it possible for example to cast the questdate into a Date field to do this?)
Typical format for questdate is "2009-04-22"
The actual tables have an encyrpted BYTEA field for the onsetdate - but I'll leave that part until later (the application is written in RoR using 'ezcrypto' to encrypt the BYTEA field).
something like
SELECT...
FROM details d
JOIN quesionnaires q ON d.id=q.id
ORDER BY LEAST (decrypt_me(onsetdate), questdate::DATE)
maybe? i'm not sure about the meaning of 'id', if you want to join by it or something else
By the way, you can leave out the explicit cast, it's in ISO format after all.
I guess you know what to use in place of decrypt_me()
There is a date parsing function in postgres: http://www.postgresql.org/docs/9.0/interactive/functions-formatting.html
Look for the to_timestamp function.
PostgreSQL supports the standard SQL CAST() function. (And a couple others, too.) So you can use
CAST (questdate AS DATE)
as long as all the values in the column 'questdate' evaluate to a valid date. If this database has been in production for a while, though, that's pretty unlikely. Not impossible, but pretty unlikely.