temp tables in postgresql - postgresql

I'm coming from a background in SQL Server where I would create temp tables using the:
select id
into #test
from table A
I've just moved into a PostGresql environment and I was hoping I could do the same, but I'm getting a syntax error. I did a search and it seems like you have to do a Create Table statement.
Is it not possible to easily create temp tables in Postgres?

Postgres supports SELECT INTO, so this should work fine:
SELECT id
INTO TEMP TABLE test
FROM a
You can also use CREATE TABLE AS:
CREATE TEMP TABLE test AS
SELECT id FROM a
This version is generally preferred, as the CREATE statement provides additional options, and can also be used in PL/pgSQL functions (where the SELECT INTO syntax has been hijacked for variable assignment).

Related

SQL DB2: Declare Temporary Table Add Column

I have declared and temporary table successfully.
DECLARE GLOBAL TEMPORARY TABLE SESSION.MY_TEMP_TABLE
LIKE MYTABLES.AN_EXISTING_TABLE
INCLUDING IDENTITY
ON COMMIT PRESERVE ROWS
WITH REPLACE;
I then use the following to merge two tables and output this into my temporary table:
INSERT INTO SESSION.MY_TEMP_TABLE
SELECT a.*
FROM (SELECT * FROM MYTABLES.TABLE_A) as a
LEFT JOIN
(SELECT * FROM MYTABLES.TABLE_B) as b
ON a.KEY=b.KEY;
Now this above all works.
ISSUE: I now want to merge on two new variables from a further table (MYTABLES.TABLE_C), however it will not let me because I declared the temporary table with a certain number of columns and I am trying to add further columns. I did a google and it seems ALTER TABLE will not work with DECLARED TEMPORARY tables, any help please?
Session tables (DGTT) need to be declared with all the required columns , as you cannot use alter table to add additional columns to a session table.
A way around this limitation is to use session tables in a different manner, specifically to create a new session table on demand with whatever additional columns you need (possibly also including the data from other tables). This can be very fast when you use the NOT LOGGED option. It also works well if your session table uses DISTRIBUTE BY HASH on environments that support that feature.
Here is an example that shows 3 session tables, the third of which has all columns from the first two tables:
declare global temporary table session.m1 like emp including identity on commit preserve rows with replace not logged;
declare global temporary table session.m2 like org including identity on commit preserve rows with replace not logged;
declare global temporary table session.m3 as (select * from session.m1, session.m2) with data with replace not logged;
If you do not want to populate the session table at time of declaration you can use DEFINITION ONLY instead of WITH DATA (or use WITH NO DATA) and populate the table later via insert or merge.

create (or copy) table schema using postgres_fdw or dblink

I have many tables in different databases and want to bring them to a database.
It seems like I have to create foreign table in the database (where I want to merge them all) with schemas of all the tables.
I am sure, there is a way to automate this (by the way, I am going to use psql command) but I do not know where to start.
what I have found so far is I can use
select * from information_schema.columns
where table_schema = 'public' and table_name = 'mytable'
I added more detail explanation.
I wanted to copy tables from another database
the tables have same column names and data type
using postgres_fdw, I needed to set up a field name and data type for each tables (the table names are also same)
then, I want to union the tables have same name all to have one single table.
for that, I am going to add prefix on table
for instance, mytable in db1, mytable in db2, mytable in db3 as in
db1_mytable, db2_mytable, db3_mytable in my local database.
Thanks to Albe's comment, I managed it and now I need to figure out doing 4th step using psql command.

Storing schema name as a variable in postgresql

I'm trying to avoid using PGSQL for some simple queries, but I want to store the schema name as a variable and use it later in multiple queries:
WITH p AS (SELECT 'testSchema' AS schemaName)
CREATE SCHEMA IF NOT EXISTS p.schemaName;
create table if not exists p.schemaName.table1;
Perhaps "with" is not the right way, or may by I need to use it differently.
You should use the SQL statement SET, perhaps with the LOCAL option, but that won't work with CREATE SCHEMA.
Something like this:
BEGIN; -- start transaction
CREATE SCHEMA IF NOT EXISTS testschema;
SET LOCAL search_path = 'testschema'; -- only for this transaction
CREATE TABLE IF NOT EXISTS table1 ...; -- will be created in testschema
COMMIT;

Selecting column name from other database table through function in PostgreSQL

Here i need to select a column name by using function(stored procedure) which is present in other database table using PostgreSQL.
I have sql server query as shown below.
Example:
create procedure sp_testing
as
if not exists ( select ssn from testdb..testtable) /*ssn is the column-name of testtable which exists in testdb database */
...
Q: Can i do the same in PostgreSQL?
Your question is not very clear, but if you want to know if a column by a certain name exists in a table by a certain name in a remote PostgreSQL database, then you should first set up a foreign data wrapper, which is a multi-stage process. Then to test the existence of a certain column in a table you need to formulate a query that conforms to the standards of the particular DBMS that you are connecting to. Use the remote information_schema.tables table for optimal compatibility (which is here specified as remote_tables which you must have defined with a prior CREATE FOREIGN TABLE command):
CREATE FUNCTION sp_testing () AS $$
BEGIN
PERFORM *
FROM remote_tables
WHERE table_name = 'testtable'
AND column_name = 'ssn';
IF NOT FOUND THEN
...
END IF;
END;
$$ LANGUAGE plpgsql;
If you want to connect to another type of DBMS, you need to write some custom function in f.i. C or perl and then call that from within a PostgreSQL function on your local machine. The test on the column is then best done inside the function which should therefore take connection parameters, table name and column name as parameters, and return a boolean to inform the result.
Before you start testing this, make sure that you read all the documentation on connecting to remote servers and learning PL/pgSQL first would also be a nice gesture to demonstrate your own efforts before you ask for help.

Select query on multiple databases

What I am trying to do is verify a URL. I just need to be able to select that single value from all databases that we have currently in SQL Server 2008. All the databases are the same, just multiple instances of the same database for different users.
I am looking to pull one item from one table in each database.
Each database contains a table SETTINGS and within that table a value for MapIconURL. I need that value from each table from within each database. I am looking at around 30 or so databases that would have this value.
So I found the "undocumented" Stored Proc sp_MsForEachDb and have working....to a point.
The code I am using is this:
EXEC sp_MsForEachDb 'use ?; SELECT "?" as databasename,SETTINGSKEYID, SECTION, NAME, INIVALUE, DESCRIPTION
FROM ?.dbo.SETTINGS
WHERE [NAME] = "MapIconURL"'
I have noticed that it is not selecting all the databases, but that it is also selecting the master table as well as other system tables, and am thinking that may be why it is not selecting all tables. Is there a way to exclude the system related tables?
If the number (and name) of the databases is fixed, then you could simply do:
SELECT MapIconUrl FROM db1.dbo.SETTINGS
UNION ALL
SELECT MapIconUrl FROM db2.dbo.SETTINGS
...
However, if either the number or names of the databases is not fixed, then you have to build the query dynamically.
First, run a query such as SELECT name FROM master..sysdatabases to get the names of the databases.
Then, loop over the result set (in T-SQL, use a CURSOR) and build your query and execute it (in T-SQL, use sp_executesql).