how to get full statement in PostgreSQL - postgresql

i wonder how to get full query statement in postgresql, when i set log_statement = 'all' in data/postgresql.conf, i can track the query record in log/ directory, but they log the query is:
LOG: Select * from table where id = $1
DETAIL: parameters: $1 = 55,
when there just a small amount param, that is clear. But if many params exist in that query,
that maybe frastrated me. if any some setting in postgresql that i need set, so i can directly get full statement such as
Select * from table where id = 55

No, there is no way to get that in the log, because that is not what arrives at the server. However, it should be easy to write a Perl (or other) script that reformats a log like that.

Related

Postgres Copy csv to table sql [duplicate]

I'm trying to run the following PHP script to do a simple database query:
$db_host = "localhost";
$db_name = "showfinder";
$username = "user";
$password = "password";
$dbconn = pg_connect("host=$db_host dbname=$db_name user=$username password=$password")
or die('Could not connect: ' . pg_last_error());
$query = 'SELECT * FROM sf_bands LIMIT 10';
$result = pg_query($query) or die('Query failed: ' . pg_last_error());
This produces the following error:
Query failed: ERROR: relation "sf_bands" does not exist
In all the examples I can find where someone gets an error stating the relation does not exist, it's because they use uppercase letters in their table name. My table name does not have uppercase letters. Is there a way to query my table without including the database name, i.e. showfinder.sf_bands?
From what I've read, this error means that you're not referencing the table name correctly. One common reason is that the table is defined with a mixed-case spelling, and you're trying to query it with all lower-case.
In other words, the following fails:
CREATE TABLE "SF_Bands" ( ... );
SELECT * FROM sf_bands; -- ERROR!
Use double-quotes to delimit identifiers so you can use the specific mixed-case spelling as the table is defined.
SELECT * FROM "SF_Bands";
Re your comment, you can add a schema to the "search_path" so that when you reference a table name without qualifying its schema, the query will match that table name by checked each schema in order. Just like PATH in the shell or include_path in PHP, etc. You can check your current schema search path:
SHOW search_path
"$user",public
You can change your schema search path:
SET search_path TO showfinder,public;
See also http://www.postgresql.org/docs/8.3/static/ddl-schemas.html
I had problems with this and this is the story (sad but true) :
If your table name is all lower case like : accounts
you can use: select * from AcCounTs and it will work fine
If your table name is all lower case like : accounts
The following will fail:
select * from "AcCounTs"
If your table name is mixed case like : Accounts
The following will fail:
select * from accounts
If your table name is mixed case like : Accounts
The following will work OK:
select * from "Accounts"
I dont like remembering useless stuff like this but you have to ;)
Postgres process query different from other RDMS. Put schema name in double quote before your table name like this, "SCHEMA_NAME"."SF_Bands"
Put the dbname parameter in your connection string. It works for me while everything else failed.
Also when doing the select, specify the your_schema.your_table like this:
select * from my_schema.your_table
If a table name contains underscores or upper case, you need to surround it in double-quotes.
SELECT * from "Table_Name";
I had a similar problem on OSX but tried to play around with double and single quotes. For your case, you could try something like this
$query = 'SELECT * FROM "sf_bands"'; // NOTE: double quotes on "sf_Bands"
This is realy helpfull
SET search_path TO schema,public;
I digged this issues more, and found out about how to set this "search_path" by defoult for a new user in current database.
Open DataBase Properties then open Sheet "Variables"
and simply add this variable for your user with actual value.
So now your user will get this schema_name by defoult and you could use tableName without schemaName.
You must write schema name and table name in qutotation mark. As below:
select * from "schemaName"."tableName";
I had the same issue as above and I am using PostgreSQL 10.5.
I tried everything as above but nothing seems to be working.
Then I closed the pgadmin and opened a session for the PSQL terminal.
Logged into the PSQL and connected to the database and schema respectively :
\c <DATABASE_NAME>;
set search_path to <SCHEMA_NAME>;
Then, restarted the pgadmin console and then I was able to work without issue in the query-tool of the pagadmin.
For me the problem was, that I had used a query to that particular table while Django was initialized. Of course it will then throw an error, because those tables did not exist. In my case, it was a get_or_create method within a admin.py file, that was executed whenever the software ran any kind of operation (in this case the migration). Hope that helps someone.
In addition to Bill Karwin's answer =>
Yes, you should surround the table name with double quotes. However, be aware that most probably php will not allow you to just write simply:
$query = "SELECT * FROM "SF_Bands"";
Instead, you should use single quotes while surrounding the query as sav said.
$query = 'SELECT * FROM "SF_Bands"';
You have to add the schema first e.g.
SELECT * FROM place.user_place;
If you don't want to add that in all queries then try this:
SET search_path TO place;
Now it will works:
SELECT * FROM user_place;
Easiest workaround is Just change the table name and all column names to lowercase and your issue will be resolved.
For example:
Change Table_Name to table_name and
Change ColumnName to columnname
It might be silly for a few, but in my case - once I created the table I could able to query the table on the same session, but if I relogin with new session table does not exits.
Then I used commit just after creating the table and now I could able to find and query the table in the new session as well. Like this:
select * from my_schema.my_tbl;
Hope this would help a few.
Make sure that Table name doesn't contain any trailing whitespaces
Try this: SCHEMA_NAME.TABLE_NAME
I'd suggest checking if you run the migrations or if the table exists in the database.
I tried every good answer ( upvote > 10) but not works.
I met this problem in pgAdmin4.
so my solution is quite simple:
find the target table / scheme.
mouse right click, and click: query-tool
in this new query tool window, you can run your SQL without specifying set search_path to <SCHEMA_NAME>;
you can see the result:

How to detect if Postgresql function utilizing index on the tables or not

I have created a PL/pgSQL table-returning function that executes a SELECT statement and uses the input parameter in the WHERE clause of the query.
I frame the statement dynamically and execute it like this: EXECUTE sqlStmt USING empID;
sqlStmt is a variable of data type text that has the SELECT query which joins 3 tables.
When I execute that query in pgAdmin and analyze I could see that 'Index scan' on the tables are utilized as expected. However, when I do EXPLAIN ANALYZE SELECT * from fn_getDetails(12), the output just says "Function scan".
How do we know if the table indexes are utilized? Other SO answers to use auto_explain module did not provide details of the function body statements. And I am unable to use the PREPARE inside my function body.
The time taken by execution of the direct SELECT statement is almost the same as the use of function, just couple of milliseconds, but how can I know if the index was used?
auto_explain will certainly provide the requested information.
Set the following parameters:
shared_preload_libraries = 'auto_explain' # requires a restart
auto_explain.log_min_duration = 0 # log all statements
auto_explain.log_nested_statements = on # log statements in functions too
The last parameter is required for tracking SQL statements inside functions.
To activate the module, you need to restart the database.
Of course, testing if the index is used in a query on a small table won't give you a reliable result. You need about as many test data as you expect to have in reality.

Create table with postgreSQL [duplicate]

I'm trying to run the following PHP script to do a simple database query:
$db_host = "localhost";
$db_name = "showfinder";
$username = "user";
$password = "password";
$dbconn = pg_connect("host=$db_host dbname=$db_name user=$username password=$password")
or die('Could not connect: ' . pg_last_error());
$query = 'SELECT * FROM sf_bands LIMIT 10';
$result = pg_query($query) or die('Query failed: ' . pg_last_error());
This produces the following error:
Query failed: ERROR: relation "sf_bands" does not exist
In all the examples I can find where someone gets an error stating the relation does not exist, it's because they use uppercase letters in their table name. My table name does not have uppercase letters. Is there a way to query my table without including the database name, i.e. showfinder.sf_bands?
From what I've read, this error means that you're not referencing the table name correctly. One common reason is that the table is defined with a mixed-case spelling, and you're trying to query it with all lower-case.
In other words, the following fails:
CREATE TABLE "SF_Bands" ( ... );
SELECT * FROM sf_bands; -- ERROR!
Use double-quotes to delimit identifiers so you can use the specific mixed-case spelling as the table is defined.
SELECT * FROM "SF_Bands";
Re your comment, you can add a schema to the "search_path" so that when you reference a table name without qualifying its schema, the query will match that table name by checked each schema in order. Just like PATH in the shell or include_path in PHP, etc. You can check your current schema search path:
SHOW search_path
"$user",public
You can change your schema search path:
SET search_path TO showfinder,public;
See also http://www.postgresql.org/docs/8.3/static/ddl-schemas.html
I had problems with this and this is the story (sad but true) :
If your table name is all lower case like : accounts
you can use: select * from AcCounTs and it will work fine
If your table name is all lower case like : accounts
The following will fail:
select * from "AcCounTs"
If your table name is mixed case like : Accounts
The following will fail:
select * from accounts
If your table name is mixed case like : Accounts
The following will work OK:
select * from "Accounts"
I dont like remembering useless stuff like this but you have to ;)
Postgres process query different from other RDMS. Put schema name in double quote before your table name like this, "SCHEMA_NAME"."SF_Bands"
Put the dbname parameter in your connection string. It works for me while everything else failed.
Also when doing the select, specify the your_schema.your_table like this:
select * from my_schema.your_table
If a table name contains underscores or upper case, you need to surround it in double-quotes.
SELECT * from "Table_Name";
I had a similar problem on OSX but tried to play around with double and single quotes. For your case, you could try something like this
$query = 'SELECT * FROM "sf_bands"'; // NOTE: double quotes on "sf_Bands"
This is realy helpfull
SET search_path TO schema,public;
I digged this issues more, and found out about how to set this "search_path" by defoult for a new user in current database.
Open DataBase Properties then open Sheet "Variables"
and simply add this variable for your user with actual value.
So now your user will get this schema_name by defoult and you could use tableName without schemaName.
You must write schema name and table name in qutotation mark. As below:
select * from "schemaName"."tableName";
I had the same issue as above and I am using PostgreSQL 10.5.
I tried everything as above but nothing seems to be working.
Then I closed the pgadmin and opened a session for the PSQL terminal.
Logged into the PSQL and connected to the database and schema respectively :
\c <DATABASE_NAME>;
set search_path to <SCHEMA_NAME>;
Then, restarted the pgadmin console and then I was able to work without issue in the query-tool of the pagadmin.
For me the problem was, that I had used a query to that particular table while Django was initialized. Of course it will then throw an error, because those tables did not exist. In my case, it was a get_or_create method within a admin.py file, that was executed whenever the software ran any kind of operation (in this case the migration). Hope that helps someone.
In addition to Bill Karwin's answer =>
Yes, you should surround the table name with double quotes. However, be aware that most probably php will not allow you to just write simply:
$query = "SELECT * FROM "SF_Bands"";
Instead, you should use single quotes while surrounding the query as sav said.
$query = 'SELECT * FROM "SF_Bands"';
You have to add the schema first e.g.
SELECT * FROM place.user_place;
If you don't want to add that in all queries then try this:
SET search_path TO place;
Now it will works:
SELECT * FROM user_place;
Easiest workaround is Just change the table name and all column names to lowercase and your issue will be resolved.
For example:
Change Table_Name to table_name and
Change ColumnName to columnname
It might be silly for a few, but in my case - once I created the table I could able to query the table on the same session, but if I relogin with new session table does not exits.
Then I used commit just after creating the table and now I could able to find and query the table in the new session as well. Like this:
select * from my_schema.my_tbl;
Hope this would help a few.
Make sure that Table name doesn't contain any trailing whitespaces
Try this: SCHEMA_NAME.TABLE_NAME
I'd suggest checking if you run the migrations or if the table exists in the database.
I tried every good answer ( upvote > 10) but not works.
I met this problem in pgAdmin4.
so my solution is quite simple:
find the target table / scheme.
mouse right click, and click: query-tool
in this new query tool window, you can run your SQL without specifying set search_path to <SCHEMA_NAME>;
you can see the result:

DB2 - If table is empty for date X, insert, else go on

--DB2 version 10 on AIX
I have a stored procedure, which I need to update. And want to check if there is data for a certain date. If data exists, go on, else run insert and then go on.
IF (SELECT COUNT(*)
FROM SCHEMA1.TABLE1_STEP1
WHERE XDATE = '9/27/2014' < 1)
THEN (INSERT INTO SCHEMA1.TABLE1_STEP1 (SELECT * FROM SCHEMA2.TABLE2 FETCH FIRST 2 ROWS ONLY))
END IF;
This errors-out.
DB2 Database Error: ERROR [42601] [IBM][DB2/AIX64] SQL0104N An unexpected token "(" was found following "/2014') < 1) THEN". Expected tokens may include: "". SQLSTATE=42601
Any thoughts on what's wrong?
I'm guessing you probably want the less than sign outside of the parenthesis...
However, as an aside, you can also do this kind of statement without an IF (although, I don't have an AIX DB2 available to check for sure. It worked on DB2 for z/OS and LUW, however):
INSERT INTO SCHEMA1.TABLE1_STEP1
SELECT *
FROM SCHEMA2.TABLE2
WHERE NOT EXISTS (
SELECT *
FROM SCHEMA1.TABLE1_STEP1
WHERE XDATE = '9/27/2014'
)
FETCH FIRST 2 ROWS ONLY
Also, you're not providing an ORDER BY on the SCHEMA2.TABLE2 select, so your results could come back in any order (whatever is "easiest" for the database engine)... order is not guaranteed unless you provide the ORDER BY statement.

SQL Injection : Syntax error

I have an essay on SQL injection ( what it is - how its done and how can it be avoided ). I get what it is and how it works. But i dont seem to be able to reproduce an injection on my database.
I made a pretty simple database ,using mysql workbench, meant for a video club. movies - stock - price - customers shopping cart etc.
I also made a pretty simple html page from which i can add movies - view what i have in stock etc.
So i have a txt field in which i enter a movie name and i get back some info for this specific movie.
The code that gets the name i type and makes the query is ::
$name = $_POST ['txtfld'];
$sql = ("SELECT * FROM test_table WHERE adad = '$Mname'");
if ($result = mysqli_query($dbc,$sql))
Now when i give 'a' as an input everything works as expected. I get back the one entry that has pk equal to [a].
Query becomes :: SELECT * FROM test_table WHERE adad= 'a'.
Next step was to see if i can get the whole table or some random entry from it.
Input was : [ a' OR 'x'='x ]
Query becomes :: SELECT * FROM test_table where adad = ' a' OR 'x' = 'x '
Everything works as expected and i get back the whole table contents.
Next step was to try inject a second query. I tried to update the test_table.
Input was :: [ a;' update test_table set asda = '123456' where adad = 'u ]
Query now becomes :: SELECT * FROM test_table WHERE adad= ' a;' UPDATE test_table SET asda ='123456' WHERE adad = 'u '
I got a syntax error so i tried every syntax i could think of including
[ a;' UPDATE test_table SET asda = '123456' where adad = 'u';# ]
. None of them worked.
Thing is, i dont really get why i get a syntax error.
For the input given above mysqli_error returns this message
error: 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 'update test_table set asda =
'123456' where adad = 'u'' at line 1
while an echo i inserted returns this
SELECT * FROM test_table WHERE adad = 'a;' UPDATE test_table SET asda = '123456' WHERE
adad = 'u'
I dont see any syntax error in the echo return and i dont get where the second [ ' ] character in the end of the mysqli_error return, comes from.
From what i understand this is rather a failure in executing a second query ( no matter what the query is - drop, insert, update )
Do i miss something?
Thanks in advance.
Michael.
mysql's PHP driver does NOT allow multiple queries in a single ->query() call, exactly for this reason. It's an anti-injection defense, to prevent the classic Bobby Tables attack. This true for all PHP db interfaces (mysql, mysqli, pdo), as they all use the same underlying mysql C api library to actually talk to the db. Any attempt to run 2+ queries in a single query call results in the syntax error.
Note that it does NOT protect against your ' or 1=1 injection, however.
In order for your stacked query injection technique to work, you will need to use the "mysqli_multi_query()" function:
http://php.net/manual/en/mysqli.multi-query.php
http://www.websec.ca/kb/sql_injection#MySQL_Stacked_Queries
MsSQL is the only database that supports stacked queries by default.
Also possibly a better injection technique, and a more reliable one, would be a UNION attack, and then dump the MySQL credentials from the "mysql.user" table, then use these to compromise the database.