Intersystems Cache Dummy Table - intersystems-cache

Does Intersystems Cache database have a dummy table similar to Oracle's DUAL?
I want to do something similar to:
SELECT 1; -- mysql
-- or
SELECT 1 FROM DUAL; -- oracle

Older versions of Cache do not support this. You can create a dummy table yourself called DUAL or DUMMY. Newer versions of Cache (2009.1+) support select with no FROM clause.

Related

Postgresql equivalent to SQL Server CONTEXT_INFO [duplicate]

In relation to my other question "What’s the best way to audit log DELETEs?". What's the PostgreSQL equivalent of CONTEXT_INFO?
I want to log deletes using a trigger, but since I'm not using the database user as my app's logical user, I cannot log the CURRENT_USER from the trigger code as the user who deleted the record. But for INSERT and UPDATE it is possible to log the record changes from trigger since you can just add a user field in the record, say inserted_by and last_updated_by, and use these fields to log to audit table.
http://www.postgres.cz/index.php/PostgreSQL_SQL_Tricks_II#Any_other_session_variables
PostgreSQL provides more variants, please, look to this site.
The accepted answer is outdated.
In recent versions of postgresql (since 9.3 or 9.4 I think), one can set / retrieve config variables are only alive for the current session [or transaction]. Documentation Reference
example of setting a session variable:
hal=# select set_config('myvar.foo', 'bar', false);
set_config
------------
bar
(1 row)
hal=# select current_setting('myvar.foo');
current_setting
-----------------
bar
(1 row)
It is possible to use the function current_setting as one would use other set returning functions.
example:
create table customers (id int);
insert into customers values (1), (2), (3), (4);
select c.*, s.*
from customers c
left join current_setting('myvar.foo') s
on c.id = length(s)

Get comparable PostgreSQL version number

I need to make sure that an available PostgreSQL version is not lower than required one. The version string could be requested as follows:
SELECT VERSION();
It returns me something like:
PostgreSQL 9.5.4, compiled by Visual C++ build 1800, 64-bit
Theoretically I could parse this string, but I am not sure that future versions of PostgreSQL server will keep this word order.
Does PostgreSQL have some predictable version report possibly split in major and minor version number?
show server_version_num; --returns 90602::text
show server_version; --returns 9.6.2::text
https://blog.2ndquadrant.com/finding-postgresql-version/ says:
You can use that more easily within an SQL query like this
SELECT current_setting('server_version_num');
You can query the PostreSql View pg_settings which is present at pg_catalog
select * from pg_settings where name like '%version%';
The query above will bring you two settings:
name other columns .....
server_version .....
server_version_num .....
For your specific case you will want the following configuration:
select name, setting, min_val, max_val
from pg_settings
where name = 'server_version_num';
name setting min_val max_val
--------------------------------------------------
server_version_num 90503 90503 90503
From here you can work with min_val and max_val
This query is equivalent to the answer provided by #ŁukaszKamiński with some more detail (if you select all columns.)

PLS-00357 sequence.nextval not allowed

I'm trying to create a trigger and am getting the error "[Error] PLS-00357: PLS-00357: Table, View Or Sequence reference 'table_data_seq.nextval' not allowed in this context"
I have read a lot of information on the error and cannot find the difference between the PL/SQL that people say works and mine. Below is my code for creating the trigger ( keeping it as basic as possible to get it working ):
create or replace trigger tr_tabData
before insert on table_data
for each row
DECLARE
seq_value int;
begin
select table_data_sq.nextval into seq_value from dual;
end;
Oracle version is 10.2.0.5
As requested here it the script for the sequence:
DROP SEQUENCE DATA_ADMIN.TABLE_DATA_SQ;
CREATE SEQUENCE DATA_ADMIN.TABLE_DATA_SQ
START WITH 1000
MAXVALUE 999999999999999999999999999
MINVALUE 1
NOCYCLE
CACHE 20
NOORDER;
This is not possible before 11g. You can use sequence_name.NEXTVAL in regular assignments from 11g not before that, and that by the following:
select TABLE_DATA_SQ.NEXTVAL into :NEW.YourID from dual;
It turned out that this was a bug with the TOAD version and my Oracle database version. The same code in SQL*Plus and SQL Developer worked as expected.

PostgreSQL, ODBC and temp table

Could you tell me why this query works in pgAdmin, but doesn't with software using ODBC:
CREATE TEMP TABLE temp296 WITH (OIDS) ON COMMIT DROP AS
SELECT age_group AS a,male AS m,mode AS t,AVG(speed) AS speed
FROM person JOIN info ON person.ppid=info.ppid
WHERE info.mode=2
GROUP BY age_group,male,mode;
SELECT age_group,male,mode,
CASE
WHEN age_group=1 AND male=0 THEN (info_dist_km/(SELECT avg_speed FROM temp296 WHERE a=1 AND m=0))*60
ELSE 0
END AS info_durn_min
FROM person JOIN info ON person.ppid=info.ppid
WHERE info.mode IN (7) AND info.info_dist_km>2;
I got "42P01: ERROR: relation "temp296" does not exist".
I also have tried with "BEGIN; [...] COMMIT;" - "HY010:The cursor is open".
PostgreSQL 9.0.10, compiled by Visual C++ build 1500, 64-bit
psqlODBC 09.01.0200
Windows 7 x64
I think that the reason why it did not work for you because by default ODBC works in autocommit mode. If you executed your statements serially, the very first statement
CREATE TEMP TABLE temp296 ON COMMIT DROP ... ;
must have autocommitted after finishing, and thus dropped your temp table.
Unfortunately, ODBC does not support directly using statements like BEGIN TRANSACTION; ... COMMIT; to handle transactions.
Instead, you can disable auto-commit using SQLSetConnectAttr function like this:
SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
But, after you do that, you must remember to commit any change by using SQLEndTran like this:
SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT);
While WITH approach has worked for you as a workaround, it is worth noting that using transactions appropriately is faster than running in auto-commit mode.
For example, if you need to insert many rows into the table (thousands or millions), using transactions can be hundreds and thousand times faster than autocommit.
It is not uncommon for temporary tables to not be available via SQLPrepare/SQLExecute in ODBC i.e., on prepared statements e.g., MS SQL Server is like this. The solution is usually to use SQLExecDirect.

How to select and delete at once in DB2 for the queue functionality

I am trying to implement simple table queue in DB2 database. What I need
is to select and delete the row in the table at once so the multiple clients will not get the same row from the queue twice. I was looking for similiar questions but they describes the solution for another database or describes quite complicated solutions. I only need to select and delete the row at once.
UPDATE: I found on the web db2 clause like this, which look exactly like what i need - the select from delete: example:
SELECT * FROM OLD TABLE (DELETE FROM example WHERE example_id = 1)
but I am wondering if this statement is atomic if the two concurent request don't get the same result or delete the same row.
Something like this:
SELECT COL1, COL2, ... FROM TABLE WHERE TABLE_ID = value
WITH RR USE AND KEEP EXCLUSIVE LOCKS;
DELETE FROM TABLE WHERE TABLE_ID = value;
COMMIT;
If you're on DB2 for z/OS (Mainframe DB2) since version 9.1, or Linux/Unix/Windows (since at least 9.5, search for data-change-table-reference), you can use a SELECT FROM DELETE statement:
SELECT *
FROM OLD TABLE
(DELETE FROM TAB1
WHERE COL1 = 'asdf');
That would give you all the rows that were deleted.
Edit: Ooops, just saw your edit about using this type of statement. And as he said in the comment, two separate application getting the same row depends on your Isolation Level.