PSQL command-line option to require transactions - psql

I'd like to stop myself from doing something stupid. I'd like to tell psql to reject any DML (updates, inserts) that isn't explicitly enclosed in a transaction.
postgres=# update "employees" set salary = salary * 1.5;
ERROR: cannot update outside of a transaction
postgres=# start transaction;
START TRANSACTION
postgres=# update "employees" set salary = salary * 1.5;
UPDATE 331805
postgres=# rollback;
ROLLBACK
postgres=#
Actually, what would be almost as good (and better in some situations) for me would be an option that forbid psql from executing any DML at all.
(Yes, in a formal sense, I could just "stop doing stupid things", but you know, baby steps.)

\set autocommit off to automatically open a new transaction and not commit it immediately if you run standalone statements. This applies to all statement types.
There's no facility to prohibit or control DML separately to DDL though. To psql they're just statements.
For scripts you should also use -v ON_ERROR_STOP=1.
If you're keen you could write an ExecutorStart_hook as a C extension loaded via session_preload_libraries that checks a configuration variable (GUC) set by the psql session and uses that to ERROR if DML is attempted while still permitting DDL (which runs through ProcessUtility_hook instead). You will need basic C programming knowledge and to read the PostgreSQL manual on extensions plus some of the example extensions.

The correct answer to do this manually in psql is:
\set AUTOCOMMIT off
(Capitals, not lowercase like in the other answer)
Note: The autocommit-on mode is PostgreSQL's traditional behavior, but autocommit-off is closer to the SQL spec. If you prefer autocommit-off, you might wish to set it in the system-wide psqlrc file or your ~/.psqlrc file.

Related

How to delete postgresql9.6 database on centos7?

I'm am using postgresql 9.6; while deleting my mrt_210119 database, getting an error like "ERROR: database "mrt_210119" is being accessed by other users DETAIL: There is 1 other session using the database"
you cannot drop a database while clients are connected to it.
then also, if you want to drop database than you need some sql statement to run which required superuser and database owner privileges .
first make sure no one connect to database further any more by using below update statement.
UPDATE pg_database SET datallowconn = 'false' WHERE datname = 'mydb';`
Below select statement terminate all current connection which is connected to database.
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'mydb';
than drop statement-
DROP DATABASE mydb;
If you have an active connection to your database, close it. If you don't, try pkill postgres and then delete.

Sybase database - Issue running stored proc

I am trying to run a stored proc "dbname..rr_deck_type_wrap_proc" through SQLDeveloper worksheet using the following code:
declare #return int, #message varchar(255)
exec #return = DBname..rr_deck_type_wrap_proc
#new_id = '123456789',
#remarks = 'Test',
#error_cd = #message output
select #return "#return", #message "#message"
However, I always get the message:
Error report - Invalid JDBC escape syntax at line position 22 '='
character expected.
This code works perfectly fine when run through another software/interface. It is probably a syntax issue with SQLDeveloper, tried different things but nothing worked. Can someone suggest anything. Thank you!
You're using 'Oracle SQL Developer' - the keyword there, being 'Oracle.'
You're connected to a SAP Sybase database. Which is perfectly fine. We provide this connectivity support for one reason, and one reason only:
To allow you to migrate it to Oracle Database.
It is NOT a T-SQL IDE. It does not provide any support really for running, debugging, playing with T-SQL.
If you have ANSI-SQL, then our parser will probably be OK with it.
If you need/want a hack, and are desperate to make your code go, then you can provide a hint to our parser, to just let the code go through to the driver, and hope it works.
An example:
/sqldev:query*/sp_help;
You could also try adding this
/*sqldev:stmt*/
This advice applies to MySQL, DB2, SQL Server, Teradata, or any other 3rd party JDBC driver we allow you to use in SQL Developer. It's there to help you move your schema and application code over into an Oracle Database.

Rails Brakeman SQL injection warning while accessing an oracle view/function

I have rails code that is consuming an oracle view/function.
This is my code:
def run_query
connection.exec_query(
"SELECT * FROM TABLE(FN_REQ(#{demo_type_param},#{demo_tid_param}}))")
end
When run Brakeman analyzer it warns of possible "sql injection attack"
I need to understand if this is a valid warning, if so, how do I remediate it?
Since this is a function & not an actual table, I am not sure what's the right way.
If it was a normal model, i would have just followed this pattern:
Model.where("mycolumn1= ? AND mycolumn2= ?", demo_type_param, demo_tid_param).first
Yes, it is real. Almost every time, you build any SQL query from simply concatenating variables, you are vulnerable to SQL injection. Generally, an SQL injection happens each time when data inserted into the query can look like valid SQL and can result in additional queries executed.
The only solution is to manually enforce appropriate escaping or to use prepared statements, with the latter being the preferred solution.
With ActiveRecord / Rails, you can use exec_query with binds directly
sql = 'SELECT * FROM TABLE(FN_REQ(?,?))'
connection.exec_query(sql, 'my query', [demo_type_param, demo_tid_param])
Here, Rails will prepare the statement on the database and add the parameters to it on execution, ensuring that everything is correctly escaped and save from SQL injection.

Postgres Query to find whether database is read-only mode

I am new to postgres. In mysql we can check whether the database is in read-only mode by triggering the below query.
SELECT ##global.read_only
Likewise can anyone pls help me with the query to do the same in postgres? I tried few things like below
SELECT schemaname||'.'||tablename FROM pg_tables
WHERE
has_table_privilege ( 'postgres', schemaname||'.'||tablename, 'select' )
AND schemaname NOT IN ( 'pg_catalog','information_schema');
But it is listing like below which I am not expecting.
?column?
----------------------------------------
public.schema_migrations
public.credential_methods
public.notifications
public.site_defaults
public.apis
public.client_applications
public.api_groups
public.operations
public.client_application_labels
public.client_application_label_values
public.roles
public.users
public.sdm_user_roles
public.permissions_roles
public.keys
public.o_two_access_tokens
public.settings
public.sdm_users
public.permissions
public.audits
public.oauth_requesttokens
public.oauth_access_tokens
public.oauth_verifiers
public.logged_exceptions
public.api_call_details
public.api_access_roles
public.api_access_users
public.login_attempts
public.system_scopes
public.keys_system_scopes
public.o_two_auth_codes
public.o_two_refresh_tokens
public.service_profiles
public.error_traces
I also tried "\du" but this one is working only in terminal but not from a ruby file.
query=ActiveRecord::Base.connection.execute("\du;")
ActiveRecord::StatementInvalid: PGError: ERROR: syntax error at or near "du"
LINE 1: du;
Thanks,
Rafiu
You probably want something of the has_*_privilege() family function for relevant tables and relevant privileges. See here. Other than that I'm not sure if postgres has a concept of read-only mode.
Well, there's also show transaction_read_only inside a read-only transaction, but that doesn't seem to be like what you're asking for. And I don't think that transaction being readonly affects privileges of the user.
I'm not sure what you expect from your query, but if you want something boolean, as in whether you have access anywhere, you can use count(*)!=0 (and, probably, not select).
If you have a multi-node instance cluster, and you have the hot standby configuration. The output of SELECT pg_is_in_recovery() can tell you if the cluster is in the read-only mode.

Invalid SQL while Embedding HSQLDB into a Rails App

I am working on porting a Rails app to JRuby and HSQLDB. My goal is to embed a database and the site within a single JAR file for deployment at customer sites. I have the site working quite well from the JAR, with a few notable problems.
When I do the following with a pretty mundane ActiveRecord model:
#total = SessionLog.count(:id)
I get the following exception:
ActiveRecord::StatementInvalid (ActiveRecord::ActiveRecordError: Not
in aggregate function or group by clause: org.hsqldb.Expression#7be117eb
in statement [SELECT count(session_logs.id) AS count_id
FROM session_logs WHERE (created_at >= '2010-02-06' AND created_at <=
'2010-03-09' AND session_type = 'tunnel_client') ORDER BY id DESC ]:
SELECT count(session_logs.id) AS count_id FROM session_logs WHERE
(created_at >= '2010-02-06' AND created_at <= '2010-03-09' AND
session_type = 'tunnel_client') ORDER BY id DESC )
It seems clear to me that the COUNT statement is causing the trouble in HSQLDB, but I'm not sure what the solution is to fix this. SQLite3 and MySQL both process this SQL statement without issue.
I'm open to using a different database other than HSQLDB, but it needs to be embeddable into our application on the JVM. That is the appeal of HSQLDB.
You've probably found a bug in the ActiveRecord adapter - activerecord-jdbchsqldb-adapter I assume.
Can you try run the SQL directly in some non-ruby SQL session? Then maybe you can see where it's going wrong and submit a bug or (better), submit a patch.
You can try H2 Database, wire it like so. From wikipedia:
The database engine is written by Thomas Mueller. He also developed the Java database engine Hypersonic SQL [1]. In 2001, the Hypersonic SQL was stopped, and the HSQLDB Group was formed to continue work on the Hypersonic SQL code. The name H2 stands for Hypersonic 2, however H2 does not share any code with Hypersonic SQL or HSQLDB. H2 is built from scratch.

Resources