Postgresql: literal table names - postgresql

I am making an application that needs to construct Postgresql queries that will execute successfully in scenarios when table names are reserved keywords etc.
In Sql Server syntax this is achieved by wrapping everything in square brackets [] i.e. SELECT * FROM [database].[schema].[table_name].
I thought the equivalent in Postgresql was the use of double quotes "" i.e. SELECT * FROM "database"."schema"."table_name".
However, when I try this in Postgresql I get the error
Relation X doesn't exist
This works:
SELECT * FROM "postgres"."schema_a".Academic_Attainment
But this doesn't:
SELECT * FROM "postgres"."schema_a"."Academic_Attainment"
Related to: Escaping keyword-like column names in Postgres
Any suggestions?

As documented in the manual unquoted identifiers are folded to lowercase.
A quoted identifier is also case sensitive, so "Foo" is a different name than "foo".
So the name Academic_Attainment is the same as academic_attainment. If you really insist on using those dreaded double quotes, then you need to use a lower case identifier:
SELECT *
FROM "schema_a"."academic_attainment"
In general it's strongly recommended to not use quoted identifiers at all. As a rule of thumb: never use double quotes and you are fine.
If you are constructing dynamic SQL, use the format() function to do that together with the %I placeholder. It will take care of quoting if necessary (and only then), e.g.
format('select * from %I.%I', 'public', 'some_table') yields select * from public.some_table but format('select * from %I.%I', 'public', 'group') yields select * from public."group"
Unrelated to your question: Postgres doesn't support cross-database queries, so you should not get into the habit including the database name into your fully qualified names. The syntax you are using only works because you are connected to the database postgres. So I would recommend to stop using the database name in any table reference.

Related

Azure data factory: pass where clause as a string to dynamic query with quotes

I have a Lookup that retrieves a few records from a MS SQL table containing schema, table name and a whole where clause. These values are passed to a copy data (within a ForEach) In the copy data i use a Dynamic query statement like:
#concat('select a.*, current_date as crt_tms from ',item().shm_nam,'.',item().tab_nam,
item().where_clause )
This construction works fine without the where_clause or with a where clause with an integer. But it goes wrong with strings like:
'a where a.CODSYSBRN ='XXX' ;'
it's about the quote (')
How can i pass it through?
I know that the where clause as a fixed string in the dynamic query works when i use double quotes (to escape the single quote):
'a where a.CODSYSBRN =''XXX'' ;'
Point is i need the where clause to be completely dynamic because it differ per table
whatever i try i get this kind of error:
Syntax error or access violation;257 sql syntax error: incorrect syntax near "where a"
ps i also tested this, but with the same result:
select a.*, current_date as crt_tms from #{item().shm_nam}.#{item().tab_nam} a #{item().where_clause}
As you have mentioned you are getting whole where clause from the lookup table, the query must have included the column values in where clause for string and integer types separately.
Example lookup table:
In your copy activity, you can use Concat() function as you were already doing it, to combine static values & parameters.
#concat('select * from ',item().schma_name,'.',item().table_name,' ',item().where_clause)
For debugging purposes, I have added the expression in set variable activity, to see the value of the expression.
Iteration1:
Iteration2:

postgres db query . How to use single quote and double quote and how to get the join working

I am using postgresdb and I ran into an issue running queries using pdAdmin...
Here are the tables that I have :
user table
There is a transaction table like this.
Here are the queries that I am looking for.
How to join the two table to get the join result on 'user.id' and 'transaction.partnerUserId' table.. when I am running it , I am not getting any result and there is the single quote and double quote confustion too..
anybody can help with the query...
Run the query as:
select "firstName", amount from "user" join transaction on "user".id = transaction."partnerUserId ;
Identifiers need to be double quoted if they are a reserved word or some form of "MixedCase" or "UPPERCASE", per documentation here Identifiers. NOTE, this is for Postgres which works opposite the SQL standard in lower casing unquoted identifiers instead of upper casing them. I personally use lower case identifiers with underscores where necessary.

Is there a way to use ::regclass in a case sensitive way?

I'm wondering if there is a way to use ::regclass to convert a string to a pg_class.oid in a way that respects case sensitivity. Let me give an example. It's often handy to use ::regclass to get the oid of a table, e.g. to list all columns of a table
SELECT * FROM pg_attribute WHERE attrelid = 'public.my_table'::regclass
However, ::regclass implicitly converts the input to all lowercase before doing the search. (This is similar to how PGSQL will interpret table names in SQL commands, if you don't surround them with double quotes.) This means if your table is called MY_table, then you cannot use casting to ::regclass to get its oid.
I know you can use other means, e.g. use pg_class.relname and pg_class.relnamespace. This question is specifically about using ::regclass, because ::regclass is more convenient (if I can find a way to make it work in a case sensitive way).
I've tried
SELECT * FROM pg_attribute WHERE attreloid = '"public.my_table"'::regclass
but that includes the double-quotes in the name it searches.
The reason my second query didn't work is because the double quotes were around the . character. So here's how to do it.
SELECT * FROM pg_attribute WHERE attreloid = '"public"."my_table"'::regclass

Postgres Syntax requiring extra ' ' and "" around things

So I am reading tutorial online and I am having a weird issue with my database when doing normal queries. So I see the following does not work:
select * from DBS
ERROR: relation "dbs" does not exist
but This works:
select * from "DBS"
When I do this it fails:
select name from "DBS"
ERROR: column "name" does not exist
but this works but doesnt actually return the correct information (it just has name for every row:
select 'name' from "DBS"
name
name
name
Is there some setting on Postgres causing this to happen?
Postgres 9.4.5 (On RDS).
select 'NAME' from "DBS";
?column?
----------
NAME
NAME
NAME
(3 rows)
When I look at select * from "DBS";
NAME
----------
default
matt
matt2
You need to specify the quotes around the table identifier, because the table uses capital letters and was created using quotes.
postgres has some distinctive behavior re: quoting
select 'name' from "DBS"
You are simply selecting the string literal 'name' once for each row in your table.
Postgres is a little unique in that it folds everything to lowercase unless you use " quotes. I suspect you created your database using pgadmin. If you create a database in pgadmin using UPPER case it will create it with UPPER case and then you will be required to use " around the name to access it. Candidly I'd rename the db to lower case and get rid of the quotes, your life will be a lot easier.

PostgreSQL - Query on hstore - column does not exists

I wonder if someone could have an idea what is going wrong with this simple query on a hstore column in PostgreSQL 9.2
The queries are runned in pgAdmin
select attributeValue->"CODE_MUN" from shapefile_feature
returns: « attributevalue » column does not exists
when doing:
select * from shapefile_feature;
all the columns are returned including attributeValue, the hstore column
what is the problem?
PostgreSQL distinguish between "identifiers" and 'literal'. Identifiers are schema, table, column's, .. names, literals are others. A attribute in hstore are not SQL identifiers. So you have to pass their names as literals. Operator "->" is only shortcut for function "fetchval(hstore, text)" with possibility be indexed.
select attributeValue->'CODE_MUN' from shapefile_feature
is internally transformed to (don't do this transformation by self!)
select fetchval(attributeValue, 'CODE_MUN') from shapefile_feature
on buggy example in transformed form, you can better understand to error message:
select fetchval(attributeValue, "CODE_MUN") from shapefile_feature
PostgreSQL tries to find column "CODE_MUN" in shapefile_feature, bacause used double quotes means identifiers (in case sensitive notation).