SAS: View to Table - view

How to create table from view?
view named A -> table named A
I find only proc sql and data set statements, but is there any native function in sas?

/* create a table as a copy of data from view by SQL ... */
proc sql;
create table A_COPY as select * from A;
quit;
/* ... or by DATA step */
data A_COPY;
set A;
run;
/* Delete the view A
and rename the table to original view name */
proc datasets lib=work nolist;
delete A / mt=view;
change A_COPY = A / mt=data;
quit;
EDIT:
you can retrieve the code that created either a DATA step view or SQL view to LOG by "describing it":
data A /view=A;
set sashelp.air;
run;
data view = A;
describe;
run;
proc sql;
create view A as select * from sashelp.air;
describe view A;
quit;

Related

Creation of Oracle temporary table with same table structure to that of a existing table

How to create a global temporary table with same table structure to that of a existing table?
I know this concept is available in SQL server like "select * into #temp123 from abc". But I want to perform the same in Oracle.
Create global temporary table mytemp
as
select * from myTable
where 1=2
Global temporary tables in Oracle are very different from temporary tables in SQL Server. They are permanent data structures, it is merely the data in them which is temporary (limited to the session or transaction, depending on how a table is defined).
Therefore, the correct way to use global temporary tables is very different to how we use temporary tables in SQL Server. The CREATE GLOBAL TEMPORARY TABLE statement is a one-off exercise (like any other table). Dropping and recreating tables on the fly is bad practice in Oracle, which doesn't stop people wanting to do it.
Given the creation of a global temporary table should a one-off exercise, there is no real benefit to using the CREATE TABLE ... AS SELECT syntax. The statement should be explicitly defined and the script stored in source control like any other DDL.
You have tagged your question [oracle18c]. If you are really using Oracle 18c you have a new feature open to you, private temporary tables, which are closer to SQL Server temporary tables. These are tables which are genuinely in-memory and are dropped automatically at the end of the transaction or session (again according to definition). These are covered in the Oracle documentation but here are the headlines.
Creating a private temporary table data with a subset of data from permanent table T23:
create table t23 (
id number primary key
, txt varchar2(24)
);
insert into t23
select 10, 'BLAH' from dual union all
select 20, 'MEH' from dual union all
select 140, 'HO HUM' from dual
/
create private temporary table ORA$PTT_t23
on commit preserve definition
as
select * from t23
where id > 100;
The ORA$PTT prefix is mandatory (although it can be changed by setting the init.ora parameter PRIVATE_TEMP_TABLE_PREFIX, but why bother?
There after we can execute any regular DML on the table:
select * from ORA$PTT_t23;
The big limitation is that we cannot use the table in static PL/SQL. The table doesn't exist in the data dictionary as such, and so the PL/SQL compiler hurls - even for anonymous blocks:
declare
rec t23%rowtype;
begin
select *
into rec
from ORA$PTT_t23';
dbms_output.put_line('id = ' || rec.id);
end;
/
ORA-06550: line 6, column 10: PL/SQL: ORA-00942: table or view does not exist
Any reference to a private temporary table in PL/SQL must be done with dynamic SQL:
declare
n pls_integer;
begin
execute immediate 'select id from ORA$PTT_t23' into n;
dbms_output.put_line('id = ' || n);
end;
/
Basically this restricts their usage to SQL*Plus (or sqlcl scripts which run a series of pure SQL statements. So, if you have a use case which fits that, then you should check out private temporary tables. However, please consider that Oracle is different from SQL Server in many aspects, not least its multi-version consistency model: readers do not block writers. Consequently, there is much less need for temporary tables in Oracle.
In the SQL Server's syntax the prefix "#" (hash) in the table name #temp123 means - create temporary table that is only accessible via the current session ("##" means "Global").
To achive exactly the same thing in Oracle you can use private temporary tables:
SQL> show parameter private_temp_table
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
private_temp_table_prefix string ORA$PTT_
create table mytab as
select 1 id, cast ('aaa' as varchar2 (32)) name from dual
;
create private temporary table ora$ptt_mytab on commit preserve definition as
select * from mytab where 1=0
;
Private TEMPORARY created.
Afterwards you can use these tables in SQL and PL/SQL blocks:
declare
r mytab%rowtype;
begin
insert into ora$ptt_mytab values (2, 'bbb');
select id + 1, name||'x' into r from ora$ptt_mytab where rownum = 1;
insert into ora$ptt_mytab values r;
end;
/
select * from mytab
union all
select * from ora$ptt_mytab;
ID NAME
---------- --------------------------------
1 aaa
2 bbb
3 bbbx
Some important restrictions on private temporary tables:
The name must always be prefixed with whatever is defined with the parameter PRIVATE_TEMP_TABLE_PREFIX. The default is ORA$PTT_.
You cannot reference PTT in the static statements of the named PL/SQL blocks, e.g. packages, functions, or triggers.
The %ROWTYPE attribute is not applicable to that table type.
You cannot define column with default values.

Sudden disappearing of data in a temporary table

I have created a temporary table and I was retrieving data from another table and inserting it to this temporary table. After that I wanted to create another temporary table and insert some data from the previous temporary table.
create global temporary table TEMP(
Col NUMBER);
insert into TEMP select COL from Table1 where COL = 1 commit;
select * from TEMP;
create global temporary table TEMP_2 (Col NUMBER);
select * from TEMP;
First off, it shows that the data is inserted in the TEMP table and then after I created a second table and did the second SELECT statement on the TEMP table, it was empty. I don't understand why!
By default, a global temporary table is created with the property "on delete commit rows". When you create another table, Oracle performs an implicit commit and so your data in the first table is deleted.
You can change this by creating the first table as:
create global temporary table TEMP(
Col NUMBER) on commit preserve rows;
Or you can reorder your statements:
create global temporary table TEMP(
Col NUMBER);
create global temporary table TEMP_2 (Col NUMBER);
insert into TEMP select COL from Table1 where COL = 1 commit;
select * from TEMP;
select * from TEMP;
Remember, in Oracle global temporary tables are permanent objects, they are not something you should normally be creating on-the-fly.

Parse a parameter to a view from a SP in Oracle 10g

I have created a VIEW by joining some number of tables. I used a SP to call that VIEW and in the SP I'm filtering the data set of the view using an ID. Now I need to pass this ID to VIEW and do the filtering inside the VIEW itself. What is the way of passing this ID as a parameter to view in Oracle 10g?
Current View
CREATE OR REPLACE FORCE VIEW "MY_VIEW"
//SELECT statements goes here
FROM MY_TABLE_1, MY_TABLE_2
//TABLE JOINS
where
//FILTERS
Current Stored Procedure
CREATE OR REPLACE PROCEDURE MY_SP
(
REQUESTACCOUNTID IN NUMBER
, p_cursor out SYS_REFCURSOR
) AS
internal_flag NUMBER;
BEGIN
open p_cursor for
SELECT //SELECT THE COLUMNS
from MY_VIEW my
WHERE my.account_id = REQUESTACCOUNTID;
END MY_SP;
What I need to do is, parse the parameter REQUESTACCOUNTID to the view while selecting
this is sorted out using a package variable. More explanation can be found using this URL

Sqlite view across multiple databases

Is it possible to create a VIEW (not temporary view) in a Sqlite database that has other databases attached to it?
The view should be able to access data from all databases via joined tables.
No, the view must be temporary, otherwise an error will occur:
sqlite> create view view1 as select * from db2.foo union select * from main.foo;
Error: view view1 cannot reference objects in database db2
sqlite> create temp view view1 as select * from db2.foo union select * from main.foo;
sqlite> select * from view1;
...
This makes sense since a temporary view is part of the automatically created temp database which only exists for the current process.
EDIT:
You can list the temporary tables and views (all stored in the automatically created temp database) this way:
sqlite> .headers on
sqlite> select * from sqlite_temp_master;
type|name|tbl_name|rootpage|sql
view|view1|view1|0|CREATE VIEW view1 as select * from db2.foo union select * from main.foo
To list views only:
select * from sqlite_temp_master where type='view';

How to insert only new ( not duplicate ) row to the existing table - in proc sql - sas?

Does any one know how to insert only "new" row to the existing table with in SAS PROC SQL ?
proc sql;
create table class as
select *
from sashelp.class
where sex = 'F';
quit;
proc sql;
create table classm as
select *
from sashelp.class
where sex = 'M' or Name = 'Alice';
quit;
proc sql;
insert into class
select *
from classm ;
quit;
The insert statement does not allow me to use where statement to insert only 10 new row from classm ( without Alice )
Is there a way to go around this ? Because I'm working with big data I would like to do this with in proc sql , or data step is fine.
Thanks
This worked for me...
proc sql;
create table class as
select *
from sashelp.class
where sex = 'F';
quit;
proc sql;
create table classm as
select *
from sashelp.class
where sex = 'M' or Name = 'Alice';
quit;
proc sql;
insert into class
select *
from classm
where name^="John";
quit;
why not use the merge?
you sort your two tables by the columns who are the reference (id) and the merge the two tables with the selected keys.

Resources