How to create a MACRO variable in SAS library with options symbolgen - permissions

I am really new to SAS and snowflake. Please correct my question, if you think there is a proper way to describe my question.
I need to build a SAS modules with following set up
options symbolgen;
%let SNOW =
"DRIVER = {SnowflakeDSIIDriver};
authenticator = https://xxx;
UID = &user.;
PWD = &pwd;
ROLE = ROLE_&sysuserid;
WAREHOUSE= AAA_BBB_CCC_WH;
DATABASE = XXX;
libname SF odbc complete = &SNOW.";
The question I am facing is how to create a table that different users with different ROLE could create different table names without changing the code.
Ritht now I have to enter my name for each table I created as:
Create or replace table AA_BB.CC_Jeff as /* my name is Jeff*/
(select ...)
My goal is to create the table as:
create table XXX.&SYSUSERID.&PROJ.yyy
&SUSUSERID should be able to auto-fill different user names to the table name.

First create a statement that works. So if the goal is to generate a statement like this statement:
libname SF odbc complete =
"DRIVER = {SnowflakeDSIIDriver};
authenticator = https://xxx;
UID = SF_USER;
PWD = SF_PASS;
ROLE = ROLE_SASUSER;
WAREHOUSE= AAA_BBB_CCC_WH;
DATABASE = XXX;
"
;
Then create macro variables that contain the parts that change and replace the example hardcoded values with references to the macro variables. So if there are three things that vary you need three macro variables.
%let db_user=SF_USER;
%let db_pass=SF_PASS;
%let sas_user=&sysuserid;
libname SF odbc complete =
"DRIVER = {SnowflakeDSIIDriver};
authenticator = https://xxx;
UID = &db_user.;
PWD = &db_pass.;
ROLE = ROLE_&sas_user.;
WAREHOUSE= AAA_BBB_CCC_WH;
DATABASE = XXX;
"
;

Related

How can you share a data table over Snowflake such that the receiver can only left-join onto it, regardless of the name of the file they are using?

I'm trying to find a way to have partners in other companies be able to left-join any of their Snowflake data tables onto one of mine (let's call it the Big Table), without giving them access to view or copy any other portion of the Big Table.
I've tried writing a UDTF that accesses a view of the Big Table, but the lack of dynamic table querying makes it impractical to share, as ideally the partner can simply input the name + location of the table they'd like to join.
I've tried writing a stored procedure, only to discover that in Snowflake shares can't be granted usage of procedures: Grant not executed: Operation not supported on a SHARE object.
It feels like I'm missing something fundamental. How can I share the Big Table securely?
I've included Snowflake SQL code below that demonstrates my attempts:
CREATE OR REPLACE SECURE FUNCTION UDTF_ATTEMPT()
RETURNS TABLE(
RECORDID STRING,
MATCHKEY VARCHAR(20),
NEW_SECURE_INFO VARCHAR(200)
)
AS
$$
SELECT C.RECORDID, C.MATCHKEY, BT.NEW_SECURE_INFO
FROM CLIENT_FILE C
LEFT JOIN BIG_TABLE_VIEW BT
ON C.MATCHKEY = BT.MATCHKEY
$$;
// Above: UDTF, but I have to predefine CLIENT_FILE which should be dynamic, OR...//
CREATE OR REPLACE PROCEDURE PROCEDURE_ATTEMPT:
(
INPUT_TABLE VARCHAR,
OUTPUT_TABLE VARCHAR
)
RETURNS FLOAT
LANGUAGE JAVASCRIPT
AS
$$
VAR SQLCOMMAND = "CREATE OR REPLACE TABLE " + OUTPUT_TABLE + " AS SELECT C.RECORDID, C.MATCHKEY, BT.NEW_SECURE_INFO FROM " + INPUT_TABLE + " C LEFT JOIN BIG_TABLE_VIEW BT
ON C.MATCHKEY = BT.MATCHKEY";
VAR STMT = SNOWFLAKE.CREATESTATEMENT(
{SQLTEXT: SQLCOMMAND}
);
VAR RES = STMT.EXECUTE();
$$;
// Stored Procedure - it's rough, but you get the idea. A copy of the UDTF, with dynamic table querying, but can't be granted usage on a share //

SSIS package insert data from CSV file to a staging table and then move from a staging table to a main table with a Site Column

I have a CSV file that successfully moves from Source File to a staging table in a Data Flow Task from a sequence container. There will be a few sequences of this. I then need to move this data from the staging table to the main table that contains an extra column (Site). I am using a SQL task to move from staging to the main table. When I run this, it goes to my staging table but, never hits my main table.
Here is my Code in my Execute SQL Task
USE ENSTRDW
UPDATE
AxonOrders
SET
AxonOrders.OrderNbr = AxonOrdersExtractCleanCreated.OrderNbr
,AxonOrders.OrderStatus = AxonOrdersExtractCleanCreated.OrderStatus
,AxonOrders.OrderEndDate = AxonOrdersExtractCleanCreated.OrderEndDate
,AxonOrders.InvoiceDate = AxonOrdersExtractCleanCreated.InvoiceDate
,AxonOrders.OrderDate = AxonOrdersExtractCleanCreated.OrderDate
,AxonOrders.RevenuePerMile = AxonOrdersExtractCleanCreated.RevenuePerMile
,AxonOrders.ReadyToInvoice = AxonOrdersExtractCleanCreated.ReadyToInvoice
,AxonOrders.OrderCommodity = AxonOrdersExtractCleanCreated.OrderCommodity
,AxonOrders.OrderTractors = AxonOrdersExtractCleanCreated.OrderTractors
,AxonOrders.BillableMileage = AxonOrdersExtractCleanCreated.BillableMileage
,AxonOrders.Site = 'GT'
,AxonOrders.LastModified = AxonOrdersExtractCleanCreated.LastModified
,AxonOrders.VoidedOn = AxonOrdersExtractCleanCreated.VoidedOn
,AxonOrders.OrderDateTimeEntered = AxonOrdersExtractCleanCreated.OrderDateTimeEntered
FROM
AxonOrdersExtractCleanCreated
Why using an UPDATE command to INSERT data?!
You should use an INSERT INTO command rather than UPDATE:
USE ENSTRDW;
INSERT INTO [AxonOrders](OrderNbr,OrderStatus,OrderEndDate,InvoiceDate,OrderDate,RevenuePerMile,ReadyToInvoice,
OrderCommodity,OrderTractors,BillableMileage,Site,LastModified,VoidedOn,OrderDateTimeEntered)
SELECT
OrderNbr,OrderStatus,OrderEndDate,InvoiceDate,OrderDate,RevenuePerMile,ReadyToInvoice,
OrderCommodity,OrderTractors,BillableMileage,'GT',LastModified,VoidedOn,OrderDateTimeEntered
FROM
AxonOrdersExtractCleanCreated

Create temporary data or table in sql and use as a database

I tried to create a temporary sql data(table) with same fields as in the original database.
What I tried..
dirname = os.path.dirname(__file__)
database = os.path.join(dirname, "database/database.db")
conn = sqlite3.connect(database)
cursor = conn.cursor()
stm = cursor.execute("CREATE TABLE new_table SELECT * FROM database;")
#and also tried with some selected fields like following
stm = cursor.execute("CREATE TABLE new_table(pressure int,parameter varchar(20),day int,month int,latitude int,longitude int,surface int);")
tables = cursor.execute("INSERT into new_table SELECT pressure,parameter, day,month,latitude,longitude,surface FROM database;")
And the error is,
sqlite3.OperationalError: near "SELECT": syntax error
How to create a new data table with selected tables or all tables(only) from the original database.
Hope someone can help me.
In your first create table you need to define it with an "as".
CREATE TABLE new_table AS (SELECT * FROM database);
This should clear up your error.

SAS SQL create table depending on macro variable result

I am struggling with creating a new table in proc sql SAS depending on macro variable result.
1) I want to check if necessary table exists.
2) If it exists then I want to create a new table with given parameters.
3) If it doesn't exist I want to create a new table with different parameters.
I think I know how to check if table exists (0 or 1 in log results):
%let tex1 = %sysfunc(exist(Base.pk_&monthP1));
%put tex1 = &tex1.;
But I do not know how to implement this result into proc sql statement.
I need sth like this:
proc sql;
create table test as
select case when &text1 = 0 then select ...
else
select ...
end ;
quit;
Thank you in advance for suggested solutions.
So if both tables have the same structure then the only part of the SQL code that needs to change is the FROM clause. It is probably easier to conditionally set a macro variable to the name to use and replace the name of the dataset with a reference to the macro variable.
select var1,varb, ....
from &dsname.
Now the problem becomes one of just setting the macro variable. You could do that with macro logic. But you could also just do that with data step logic.
data _null_ ;
if exist("Base.pk_&monthP1") then call symputx('dsname','table1');
else call symputx('dsname','table2');
run;
proc sql;
... from &dsname. ...

SQL: update table using create statement

I am using the following to update fields in my SQL table:
private String updateData(Handle handle, String username, String name, String table) {
handle.createStatement("sql/Create.sql")
.bind("playername", name)
.bind("tablename", table)
.execute();
}
The Create.sql file is as follows:
UPDATE :tablename SET varname = :playername where name = :username
I know that it is not working because :tablename is a string variable. What code do I write for SQL to recognize the table name as if I actually typed it as hard code?
You cannot pass table name as a parameter - only data can be passed. You need to change the string and "paste" the table name into SQL itself. Very important note: you must make sure that the value of the table variable does not come from any kind of user input. Otherwise, you are opening up your code to SQL Injection attacks.
String sql = String.format("UPDATE %s SET varname = :playername where name = :username", table);
handle.createStatement(sql).bind("playername", name).execute();
If the value of table does come from user input, change the code to use different hardcoded or pre-configured strings defined within your program.