How to Drop All tasks in Snowflake - snowflake-cloud-data-platform

What is the simplest way to drop all tasks in Snowflake under a specific schema? I'm hoping this won't require some sort of Javascript loop.
I'm hoping for something like ... :)
DROP ALL TASKS IN <SCHEMA>
Going through it one by one can be cumbersome.
Did not see anything in the documentation that alluded to this: https://docs.snowflake.com/en/sql-reference/sql/drop-task.html

You can use the show tasks, followed by a select statement to generate the DDL you can then run as a SQL script.
use database "mydatabase";
use schema "myschema";
show tasks;
SELECT 'DROP TASK ' || "name" || ';' FROM table(result_scan(last_query_id()));

I had exactly the same requirement once. I ended up with:
-- SHOW TASKS IN SCHEMA ...;
SHOW TASKS IN DATABASE;
SELECT LISTAGG(REPLACE('DROP TASK IF EXISTS <TASK_NAME>;' || CHAR(13),
'<TASK_NAME>'
,CONCAT_WS('.', "database_name","schema_name", "name"))
,'') AS drop_all_task_script
FROM TABLE(result_scan(last_query_id()));

Related

Snowflake data unloading - multiple tables

Does snowflake provide any utility to unload data from multiple tables at the same time? Somewhat similar to expdp (or export) in Oracle? I can write a procedure to fetch table names and copy/unload to stage files, but was wondering if there is any other utility that might be available out of the box in snowflake for this?
Also it would be helpful if someone can point out approach or best practices to use for schema refreshes.
You can do what I mention above with SQL like this:
create table test.test.table_to_export(full_table_name text, write_path text);
create table test.test.table_a(id int);
insert into test.test.table_to_export values ('test.test.table_a', 'table_a/a_files_');
Then running this will use COPY TO to write you my_stage in the form of this example for each row in the at the same time point, so the data is coherent between them (via time travel) thus this method would only work on permanent tables.
declare
c1 cursor for select full_table_name, write_path from test.test.table_to_export;
sql text;
sql_template text;
id text;
begin
select 1;
select last_query_id(-1) into id;
sql_template := $$copy into #my_stage/result/WRITE_PATH FROM (select * FROM TABLE_NAME AT(STATEMENT => '$$ || id || $$'))
file_format=(format_name='myformat' compression='gzip');$$;
for record in c1 do
sql := replace(replace(sql_template, 'TABLE_NAME', record.full_table_name), 'WRITE_PATH', record.write_path);
execute immediate sql;
end for;
end;

How can I find DDL statements run against Database/schemas

I have specific requirement where I need to find only DDL ran against my snowflake database/schema during specific period of time , how can we find using query_history or any other method, any idea??
It is possible using QUERY_HISTORY:
SELECT *
FROM TABLE(INFORMATION_SCHEMA.QUERY_HISTORY())
-- END_TIME_RANGE_START/END_TIME_RANGE_END to get specific time range
WHERE DATABASE_NAME ILIKE '<db_name>'
AND SCHEMA_NAME ILIKE '<schema_name>'
AND QUERY_TYPE ILIKE ANY ('CREATE%', 'ALTER%', 'DROP%', 'DESCRIBE%');
The QUERY_TYPE column contains values that are more descriptive like: CREATE_VIEW/CREATE_TABLE_AS_SELECT/CRATE_TABLE/ALTER_TABLE_ADD_COLUMN etc.
To retrieve entire class of DDL commands, wildcard pattern was used CREATE% or ALTER%. It could be further tweaked depending on specific needs.

legacy table, investigate how it gets updated?

I have a legacy database that is a mess. I need to investigate a specific table that gets synced/updated using several sources… I need to know when and how the table gets updated.
How can I retrieve all the sources used to update/sync this table? (I guess it’s mainly done through different jobs using SPs).
Is there a way to search in all SP for ‘%table name%’ ?! (is the only way I can think of, is there any other reasonable way?)
Then, I would just need to check which jobs are running those SP, and I could get a better picture…
This will generate list of all procs that refer to a object 'UserInfo':
> select object_name(object_id) from sys.sql_modules where
> charindex('userinfo',definition)>0
This will not search SSIS or BCP packages which typically are on the file system or in the MSDB database. Many times there are jobs that invoke BCP and/or SSIS packages that update data.
To inspect only procedures you can use:
> select object_name(sm.object_id) from sys.sql_modules sm inner join
> sys.objects so on sm.object_id=so.object_id where
> charindex('userinfo',definition)>0 and type='P'
You could try this approach too (looking for ones where is_updated is 1) but I would combine it with other approaches as I haven't found this to be 100% reliable.
DECLARE #TwoPartName nvarchar(500) = '[dbo].[YourTable]';
SELECT referencing_schema_name,
referencing_entity_name,
MAX(0 + is_selected) is_selected,
MAX(0 + is_updated) is_updated
FROM sys.dm_sql_referencing_entities (#TwoPartName, 'OBJECT')
CROSS APPLY sys.dm_sql_referenced_entities (QUOTENAME(referencing_schema_name) + '.'
+ QUOTENAME(referencing_entity_name), 'OBJECT') CA2
WHERE CA2.referenced_id = OBJECT_ID(#TwoPartName)
GROUP BY referencing_schema_name,
referencing_entity_name;
You can start by generating the "CREATE" scripts via the "Tasks / Generate Scripts..." command ...
...for the stored procedures and functions defined in your database.
Then you can search the generated SQL files to see where your table of interest is referenced.
This will not indicate anything about applications with internal SQL that updates your table, but it is a good start for your analysis.

T-SQL - Where is #tempimport?

I have a legacy db from an application that is no longer supported. I'm trying to deconstruct a stored procedure to make a modification, but I can't figure out where #tempimport is located. I've searched high and low through the schema, but I'm not finding anything close. This is how it's used:
SET NOCOUNT ON;
DECLARE #saleid UNIQUEIDENTIFIER
SELECT TOP 1 #saleid = [sale_id] FROM #tempimport;
Is this a T-SQL specific thing, or can I actually find the data in this table somewhere?
Tables with the # preceding the name are temporary tables.
You can find them in the tempdb database under System Databases
Tables that are prefixed with a # are temporary tables that are created in the tempdb system database.
try to find code of this table creation in you DB schema
select * from information_schema.routines
where object_definition(object_id(routine_name)) like '%#tempimport%'
try find #tempimport in schemas of neighboring DBs
try find #tempimport in your application sources if exists.
try to profile(SQL Profiler tool) your application and search #tempimport here.
Additional
#tempimport can be created by any connected application. Not only from your DB runnable code
you can research deeper and try to monitoring the moment of #tempimport creation. Example
select left(name, charindex('_',name)-1)
from tempdb..sysobjects
where charindex('_',name) > 0 and
xtype = 'u' and not object_id('tempdb..'+name) is null
and left(name, charindex('_',name)-1) = '#tempimport'
source: Is there a way to get a list of all current temporary tables in SQL Server?

How to create UPDATE from exported data?

I'd like to get data from one database..table into an UPDATE script that can be used with another database..table. Rather than doing export from DB1 into DB2, I need to run an UPDATE script against DB2.
If the above is not possible, is there a way to generate the UPDATE syntax from DB1..table1:
col1 = value1,
col2 = value2,
col3 = value3,
...
--- EDIT ---
Looking through the answers, there's an assumption that DB1 is available at the same time that DB2 is available. This is not the case. Each database will know nothing of the other. The two servers/databases will not be available/accessible at the same time.
Is it possible to script the table data into a flat file? Not sure how easy that will be to then get into an UPDATE statement.
Using a linked server and an update statement will really be your easiest solution as stated above, but I do understand that sometimes that isn't possible. The following is an example of dynamically building update statements. I am assuming there is no chance of SQL Injection from the "SourceData" table. If there is that possibility then you will need to use the same technique to build statements that use sp_executesql and parameters.
SELECT 'UPDATE UpdateTable ' +
' SET FieldToUpdate1 = ''' + SourceData.DataToUpdate1 + '''' +
' , FieldToUpdate2 = ' + CAST(SourceData.DataToUpdate2 AS varchar) +
' WHERE UpdateTable.PrimaryKeyField1 = ' + CAST(SourceData.PrimaryKey1 AS varchar) +
' AND UpdateTable.PrimaryKeyField2 = ''' + SourceData.PrimaryKey2 + ''''
FROM SourceData
Also here is a link to a blog I wrote on Generating multiple SQL statements from a query. It's a bit more simplistic than the type of statement you are trying to create, but it should give you an idea. Also here is an article I wrote on using Single Quotation Marks in SQL. Other than that you can go onto Google and search for "SQL Server Dynamic SQL" and you will get hundreds of blogs, articles, forum entries etc on the subject.
Your question needs a little more clarification to be completely understand what you are trying to accomplish, but assuming the databases are on the same server, then you should be able to do something like this using UPDATE and JOIN:
UPDATE a
SET col1 = value1, col2 = value2
FROM database1.schema.table a
JOIN database2.schema.table b
ON a.primaryKey = b.primaryKey
Alternatively, if they are on different servers, you could setup a linked server and it should work similarly.
I think you still want to INSERT from one table into another table of another database. You can use INSERT INTO..SELECT
INSERT INTO DB2.dbo.TableName(Col1, Col2, Col3) -- specify columns
SELECT Col1, Col2, Col3
FROM DB1.dbo.TableName
Assuming dbo is the schema used.
Are both databases on the same SQL-Server? In that case, use fully-qualified table names. I.e.:
Update Database1.Schema.Table
SET ...
FROM
Database2.Schema.Table
If they're not on the same server, then you can use linked servers.
I'm not sure of the SQL server syntax but you can do something like this to generate the update statement.
SELECT 'UPDATE mytable SET col1=' || col1 || ' WHERE pk=' primaryKey ||';' FROM mytable;
Obviously you'll need to escape quotes, etc. depending on the value types.
I assume this is because you can't do a normal UPDATE from a SELECT?

Resources