PostgreSQL - how to drop a user with hyphen in his username - postgresql

I can't seem to execute DROP USER username if the username contains hyphens (-), like for example user-name.
I tried a straightforward DROP USER user-name, also DROP USER 'user-name' but I'm getting: ERROR: syntax error at or near "'user-name'".
I would guess I need to use some kind of escaping or something.

Identifiers need to be quoted using double quotes, single quotes are for string literals:
DROP USER "user-name";
More details in the manual: http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS

Related

How to fix default wrong character encoding in phpMyAdmin SQL? (Single quotes in SQL statements are generating syntax errors)

I am running SQL queries using phpMYAdmin and getting syntax errors when entering single-quotes by keyboard.
When I use single-quotes entered by keyboard, as opposed to using phpMyAdmin auto-generated SQL statements, I get a syntax error. (Exactly the same SQL statement that works, no problem, from the auto-generated SQL statement)
The single-quotes look different when entered by keyboard then those that are auto-generated by phpMyAdmin.
As you can see in the image, the single-quotes for 'id', 'name' (quotes provided by phpMyAdmin's auto-generated code) are different than '3', 'Lawyers' (the type of single-quotes that show up when entered by keyboard).
Is this a bad setting on my laptop (Windows 10), or within phpMyAdmin?
How can I fix this?
The backticks (`) are used by MySQL to indicate database, table, and column names. Single quotes (') are used to indicate a string value. So the syntax used by phpMyAdmin is correct here. The trouble you're having with the SQL you're entering manually is because MySQL differentiates between the backtick and single quote; using the single quote for column names is incorrect here.
You can often omit the backtick entirely; it's needed specifically when the database/table/column name is also a MySQL keyword (date, for instance), and as you've seen can usually be left out entirely.
For further details and list of Keywords and Reserved Words in MySQL (v5.7) see 10.3 Keywords and Reserved Words in the MySQL documentation.

Postgresql : Search field contain tab character. (With LIKE)

I'm searching how to check if any field contains the TAB character.
after read this post, I tried to use this command :
SELECT id FROM account WHERE description LIKE '%\t%';
But it returns me all fields that contain the 't' character.
Do you have any solution to represent the TAB character ?
In SQL there is no "escaping" of characters like \t. You can use the chr() function for this:
select id
from account
where description LIKE '%'||chr(9)||'%'
I prefer the strpos function in this case, because I think it makes the intention clearer
select id
from account
where strpos(description, chr(9)) > 0
you have to use a literal tab chacater,
SELECT id FROM account WHERE description LIKE '% %';
In psql type ctrl-V and then TAB to enter a tab. in other environments there are other ways to enter literal tabs.
Alternatively you can use escape string syntax: e'%\t%', or octal escape e'%\011%'.
I'm very late to this party, but having looked into this today, I've found you can also use regular expression.
SELECT id FROM account WHERE description ~ '\t';

How do you alter a SQL Server credential that contains square brackets?

I want to alter a credential on my SQL Server install. It was auto-generated when I set up a replication publication to be used with the replication transaction log reader proxy. Apparently it was generated with square brackets as part of its name because when I select from sys.credentials, its entry's name is [REPL][BACP\jeremy][DAVEG1525-162-AssessmentSystemLiveTest-1].
How can I alter its credential? I tried this:
ALTER CREDENTIAL [REPL][BACP\jeremy][DAVEG1525-162-AssessmentSystemLiveTest-1] WITH IDENTITY = N'BACP\jeremy', SECRET = N'NewPasswordHere'
However it says that this is incorrect syntax. The MSDN page for ALTER CREDENTIAL only gives examples for credentials whose name doesn't contain square brackets. How can I alter this credential?
This actually worked:
ALTER CREDENTIAL [[REPL]][BACP\jeremy]][DAVEG1525-162-AssessmentSystemLiveTest-1]]] WITH IDENTITY = N'BACP\jeremy', SECRET = N'NewPasswordHere'
Escaping square brackets in SQL Server is not nice. :-)
You can escape [] brackets as shown in this post:
How can I escape square brackets in a LIKE clause?
Hopefully that will point you in the right direction.

PostgreSQL - Deleting a database with forward slash in its name

In my Ruby-on-Rails database.yml file, I accidentally created a PostgreSQL database with a forward slash (/) in its name.
I have been unable to remove this database via psql commands, trying with various escape sequences.
Surround your database name in quotes:
DROP DATABASE "database/withslash";
From the Identifiers and Keywords documentation:
There is a second kind of identifier: the delimited identifier or quoted identifier. It is formed by enclosing an arbitrary sequence of characters in double-quotes ("). A delimited identifier is always an identifier, never a key word. So "select" could be used to refer to a column or table named "select", whereas an unquoted select would be taken as a key word and would therefore provoke a parse error when used where a table or column name is expected. The example can be written with quoted identifiers like this:
UPDATE "my_table" SET "a" = 5;
Quoted identifiers can contain any character, except the character with code zero.
Do note that quoted identifiers are case sensitive.
You cannot drop a database while connected to that database though, so maybe you want to use the command line dropdb command. Your shell will parse the quotes, so you want to escape the quotes:
dropdb \"database/withslash\"

How to escape string while matching pattern in PostgreSQL

I want to find rows where a text column begins with a user given string, e.g. SELECT * FROM users WHERE name LIKE 'rob%' but "rob" is unvalidated user input. If the user writes a string containing a special pattern character like "rob_", it will match both "robert42" and "rob_the_man". I need to be sure that the string is matched literally, how would I do that? Do I need to handle the escaping on an application level or is it a more beautiful way?
I'm using PostgreSQL 9.1 and go-pgsql for Go.
The _ and % characters have to be quoted to be matched literally in a LIKE statement, there's no way around it. The choice is about doing it client-side, or server-side (typically by using the SQL replace(), see below). Also to get it 100% right in the general case, there are a few things to consider.
By default, the quote character to use before _ or % is the backslash (\), but it can be changed with an ESCAPE clause immediately following the LIKE clause.
In any case, the quote character has to be repeated twice in the pattern to be matched literally as one character.
Example: ... WHERE field like 'john^%node1^^node2.uucp#%' ESCAPE '^' would match john%node1^node2.uccp# followed by anything.
There's a problem with the default choice of backslash: it's already used for other purposes when standard_conforming_strings is OFF (PG 9.1 has it ON by default, but previous versions being still in wide use, this is a point to consider).
Also if the quoting for LIKE wildcard is done client-side in a user input injection scenario, it comes in addition to to the normal string-quoting already necessary on user input.
A glance at a go-pgsql example tells that it uses $N-style placeholders for variables... So here's an attempt to write it in a somehow generic way: it works with standard_conforming_strings both ON or OFF, uses server-side replacement of [%_], an alternative quote character, quoting of the quote character, and avoids sql injection:
db.Query("SELECT * from USERS where name like replace(replace(replace($1,'^','^^'),'%','^%'),'_','^_') ||'%' ESCAPE '^'",
variable_user_input);
To escape the underscore and the percent to be used in a pattern in like expressions use the escape character:
SELECT * FROM users WHERE name LIKE replace(replace(user_input, '_', '\\_'), '%', '\\%');
As far as I can tell the only special characters with the LIKE operator is percent and underscore, and these can easily be escaped manually using backslash. It's not very beautiful but it works.
SELECT * FROM users WHERE name LIKE
regexp_replace('rob', '(%|_)', '\\\1', 'g') || '%';
I find it strange that there is no such functions shipped with PostgreSQL. Who wants their users to write their own patterns?
The best answer is that you shouldn't be interpolating user input into your sql at all. Even escaping the sql is still dangerous.
The following which uses go's db/sql library illustrates a much safer way. Substitute the Prepare and Exec calls with whatever your go postgresql library's equivalents are.
// The question mark tells the database server that we will provide
// the LIKE parameter later in the Exec call
sql := "SELECT * FROM users where name LIKE ?"
// no need to escape since this won't be interpolated into the sql string.
value := "%" + user_input
// prepare the completely safe sql string.
stmt, err := db.Prepare(sql)
// Now execute that sql with the values for every occurence of the question mark.
result, err := stmt.Exec(value)
The benefits of this are that user input can safely be used without fear of it injecting sql into the statements you run. You also get the benefit of reusing the prepared sql for multiple queries which can be more efficient in certain cases.