How to specify potentially reserved words as strings in Postgres query? - postgresql

I've been using MySQL for close to 10 years, but have recently jumped into a project that's exposed me to Postgres for the first time. Most of the differences aren't a bit deal, but I have been running into some small issues along the way that are throwing me off.
My latest one just has me stuck. I'm sure it's a simple work-around, but I haven't been able to find it. I need to update a set of records and the column name is, "view" - which is more than likely the cause of this issue, and my own dump fault. But I can't figure out how to get around it.
Here's my query:
UPDATE rv_template_fields SET view = "display_type_1"
WHERE rv_template_fields.view = "display_type_2"
It's causing the error:
ERROR: column "display_type_1" does not exist
It's clearly jumping past the column named "view". I'm not sure how to specify that as a string and not a reserved word.

For string literals, you should you single quote instead of double quote:
UPDATE rv_template_fields SET view = 'display_type_1' WHERE rv_template_fields.view = 'display_type_2'
Double quotes are for quoting identifiers of fields and relations, like, for instance view, so that you could write also:
UPDATE rv_template_fields SET "view" = 'display_type_1' WHERE "view" = 'display_type_2'

It has nothing to do with view: In postgres, double quotes (") are like backticks in mysql - if you code "display_type_1", you're telling postgres to use the identifier display_type_1.
Use single quotes for string literals:
UPDATE rv_template_fields SET view = 'display_type_1'
WHERE rv_template_fields.view = 'display_type_2'
Use double quotes when you have a (poorly named) identifier that's reserved word, like select * from "join" if your table name is literally join etc.

Related

Why single quote escape cannot be used in QuestDB, Error: dangling expression

I'm trying to use Query Variables in Grafana, the panel query source is PostgreSQL for QuestDB.
I have added the variable without any issue, but I'm unable to use the variable in Panel query since the variable values contains the spaces (SENSOR01 ON_OFF), also I'm unable to figure-out how to add single quote escape.
Following are the scenarios I tried:
Scenario1: this indicates due to space in the Variable value, on_off considered as separate word
where sensor_name = $sensor
db query error: pq: unexpected token: on_off
.
.
Scenario2: tried to add single quotes explicitly for the variable value, but there is generic error from source DB (QuestDB)
where sensor_name = concat('''', $sensor, '''')
db query error: pq: dangling expression
When tried Scenario2 approach directly in query of Variable, getting the same error
..
Scenario3: Hard-coded the variable value with space and with single quotes, but this giving me error with first part of the variable, looks like the hard-coded single quotes not passed here!
Error (Scenario3):
Is there any way/workaround to tackle this issue?
Could you just add the quotes directly in the query?
where sensor_name = '$sensor'
I have a similar grafana panel querying a questDB database using a variable and it works for me. This is my query:
select device_type, avg(duration_ms) as avg_duration_ms, avg(speed) as avg_speed, avg(measure1) as avg_m1, avg(measure2) as avg_m2 from ilp_test
WHERE
$__timeFilter(timestamp) and device_type = '$deviceType'
A rather hacky workaround would be to do:
where sensor_name = concat(cast(cast('&' as int) + 1 as char), $sensor, cast(cast('&' as int) + 1 as char))
This should work, but I'm pretty sure there is a better solution. Let me find it and get back to you.
Update. We may support Postgres syntax (which is '' escaping for a single quote char) in one of upcoming versions. For now, you'd have to use the above workaround.

Grafana (V7) adding variable in table name

I need to be able to use variables in table names - I basically have the same set of tables used for different types of data, so I would like to just have one dashboard and swapping between all types instead of always having to set up multiple identical dashboards.
My query is something like:
select * from table_$variable_name;
Where my list of possible variable is something like cat, dog, bird
I can seem to make this work, if I only put the variable as shown above I get the following error
Error 1146: Table 'table_$variable_name' doesn't exist
If I enclose it in curly brackets, I get this error instead.
Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '{bird}' at line 1
(i.e. with the selected variable actually being visible this time)
I'm not sure if the issue is having underscores in the table names, I tried putting underscores around my variables too to check and I had no luck with that.
Another thing I tried was gradually adding on to the table name, so e.g.
select * from table_$variable;
Still returns an error, but I can see the table name starting to form correctly
Error 1146: Table 'table_bird_' doesn't exist
However, as soon as I add another underscore, the variable is not picked up abymore
```Error 1146: Table 'table_$variable_' doesn't exist``
I'm sure it's something silly I am missing in the syntax of the query - anyone has any suggestions?
Using this https://grafana.com/docs/grafana/latest/variables/templates-and-variables/ for reference
As #arturomp suggests, use
${var:raw}
At least in my case, this was the solution that worked.
I found double square brackets work. e.g.
Rather than
select * from table_$variable_name;
use
select * from table_[[variable_name]];

TSQL Find and Replace in String

I have a table that I use for error logging when inserts fail on the front end of my site. It stores the params URL as a text string so we can see what values were sent over and why it may have failed.
Well I am now working with this data to try and recover some records from it.
This is what the record looks like in my field:
xml=<data><optional><Account>192070041</Account></optional></data>, submitter=Q1370, target=Q1234, escalationType=esc, escalationReason=277, feedback=cx req live esc to have us release his alh payment for 8487.18, adv cx his funds are eligble for release on july 2nd at 445 pm est, preventable=0,
The issue I am running into recovering some data is that on a script I am writing in PHP, I am getting all of the params individualy by exploding on the = sign to get each of the values.
Well, the feedback= section happens to be comments that contains commas and its messing up a lot of stuff.
What I need to do is within the string, I need to find everything in feedback=xxxxxxxxxx, and either remove all the commas from that section or replace with with a | pipe so I can just change them back later.
My lack of knowledge in this area is where I hope some one can point me in the right direction so I can get some records restored on a mass level.
Example:
Before String - param1=dfsfsf, param2=fdsfsdfds, param3=bob, how are you doing today?
After String - param1=dfsfsf, param2=fdsfsdfds, param3=bob| how are you doing today?
UPDATE YourTable SET URL=REPLACE(URL,',','|')
See https://msdn.microsoft.com/en-us/library/ms186862.aspx and https://msdn.microsoft.com/en-us/library/ms181984.aspx
Later edit: I read your question more carefully and I now understand that you want to replace only the commas in after a certain substring. Try something like this:
DECLARE #URL NVARCHAR(1000)
SET #URL='Before String - param1=dfsfsf, param2=fdsfsdfds, param3=bob, how are you doing today?'
SELECT LEFT(#URL,ISNULL(NULLIF(CHARINDEX('param3=',#URL),0),LEN(#URL)))
+ISNULL(REPLACE(SUBSTRING(#URL,NULLIF(CHARINDEX('param3=',#URL),0),1000),',','|'),'')

How to handle backslash(\) in ENCRYPE/DECRYPT

I m using a update Query.
i.e:-
UPDATE tbl_ecpuser
SET ecpuser_fullname = 'Operator',
ecpuser_password = encrypt(E'Op1111/1\1/1\1' , 'ENCRYPE_KEY', 'ENCRYPE_ALGORITHM'),
where ecpuser_key = '0949600348'
Query is Executing Successfully.
But when I m trying to retrive the value for the Column ecpuser_password, it
returns with some extra character (i.e-00)
The Query for the Retrive the Password is:-
SELECT
decrypt(ecpuser_password,'ENCRYPE_KEY','ENCRYPE_ALGORITHM') AS PASSWORD
FROM tbl_ecpuser
WHERE
ecpuser_key = '0949600348'
This query returens
"Op1111/1\001/1\001"
but it should return "Op1111/1\1/1\1" and I need this.
So can any body help me about this.
Thanks.
One place where PostgreSQL was not conforming to the SQL standard was the treatment of a backslash in string literals.
Since 8.2 a configuration property standard_conforming_strings is available that configures PostgreSQL to comply with the standard here.
If you set that to "on" '\1' is treated correctly as a string with two characters (one backslash and the character 1).
However if that is turned on, the prefix E enables escape sequences again.
So (if I understand your problem correctly) you should set standard_conforming_strings = on and specify the string literal without the leading E.
Seems like E'\1' is treated as chr(1) and returned accordingly.
You probably want: E'\\1'.

How to set null values while importing to phpmyadmin?

I'm trying to import a .csv file into phpmyadmin where several fields are purposefully left blank. I need these field to register as null values and not just left as a blank string.
I know in the field properties you can select to allow "null" vs. "not null" for each field, but it still doesn't change cell to a null value while importing. After the import I can manually go check the null box for each field on each record, but that it unrealistic considering the amount of data I'm working with.
Is there a way to get phpmyadmin to set these blank cell to null values on import?
I've been experience similar issues.
If you download a PhpMyAdmin CSV file with NULL values, you'll notice that NULL doesn't get encapsulated with quotes. So you'll have a line like this:
"1";"2";NULL;NULL
"2";"2";NULL;NULL
etc.
However, if you edit a CSV file in something like Open Office Calc, it might change this to put quotes around NULL, like so:
"1";"2";"NULL";"NULL"
"2";"2";"NULL";"NULL"
etc.
What should work is doing a search and replace for ["NULL" = NULL].
In your case, because you have empty (blank) fields, you'll be looking at doing a search and replace like this:
[,, = ,NULL,]
And probably a second pass for NULL values at the end of a line like so:
[,\n = ,NULL\n]
Ancient question, but in case another MySQL noob like myself comes across it.
The find/replace rigamarole jmbertucci describes is avoidable if you're in charge of the creation of the CSV file, for example when you're backing up your own databases. In phpMyAdmin, if you select "custom" export method, you will see replace NULL with: and the default is NULL. Simply change that to "NULL" and you save yourself a step.
I ran into this same problem and jmbertucci's answer worked great. I did run into one additional problem. In the case with a row of data like such
"hello","world",,,,,,
which has multiple sets of null values in a row doing a search replace with [,, = ,NULL,] as jmbertucci suggested won't work as you intend it to on the first pass. Instead you'll end up with
"hello","world",NULL,,NULL,,NULL
You should continue to do the search replace to until you end up with 0 occurrences replaced