I use the query below to get the information of transient tables on my whole account and unable to fetch any result for that.
There are two transients table already created and I can access them. All are done from the highest role accountadmin only.
select * from "SNOWFLAKE"."ACCOUNT_USAGE"."TABLES" WHERE TABLE_TYPE <> 'BASE TABLE';
Gives me empty.
If I do with use DATABASE TRANSIENT_DB;
show tables history;
I get both transient and temporary table I created, I would like to like all the tables that are transients/temporary across the account and not under database alone. Any help on this will be appreciated.
as per Snowflake there is a latency From 45 minutes to 3 hours (varies by view) for the information to be available in the Schema.
You can test this by yourself and will see the objects are not avialbe as sson as you create but are available in information_schema
https://docs.snowflake.com/en/sql-reference/account-usage.html
create table Nor_tab(fld1 varchar2(100));
create transient table tran_tab(fld1 varchar2(100));
select * from snowflake.account_usage.tables where table_name like 'NOR%';
select * from information_schema.tables where table_name like 'NOR%';
Related
I am creating a security layer on few databases. As part of that I have to create a view in Original_Database that joins two tables (union) from different databases, Chained_Database1 and Chained_Database2.
USE Original_Database;
GO
CREATE VIEW QueryATable
AS
SELECT * FROM Chained_Database1.dbo.ATable
UNION
SELECT * FROM Chained_Database2.dbo.ATable;
GO
If user usergroupA (Usergroup) logs in and selects from the view QueryATable from Original_Database then he should be able to see only data from Chained_Database1.dbo.ATable.
Likewise if usergroupB logs in and selects from the view QueryATable, then he should be able to see only data from Chained_Database2.dbo.ATable.
I have tried giving different permissions to the users. It's either denying view access or giving result from two tables.
Your help is highly appreciated.
Thanks in advance!
Based on your requirements, the UNION is pointless and would only slow performance since you would select from both data sets... and then explicitly limit it to one. Theoretically you'd have a look up table for the user who ran the query, and you'd limit the results in the WHERE clause since you can't user parameters in a view. So, don't do the union. Instead create two separate views.
CREATE VIEW QueryATable
AS
SELECT * FROM Chained_Database1.dbo.ATable
GRANT SELECT ON QueryATable TO <who ever...>
GO
CREATE VIEW QueryBTable
AS
SELECT * FROM Chained_Database2.dbo.ATable
GRANT SELECT ON QueryBTable TO <who ever...>
GO
If you don't want to create separate views then you could handle this in a STORED PROCEDURE or some other way perhaps...
CREATE PROCEDURE yourProcedure(#userID)
AS
IF 1 = (SELECT COUNT(*) FROM LookUpTableA WHERE userID = #userID)
SELECT * FROM Chained_Database1.dbo.ATable
IF 1 = (SELECT COUNT(*) FROM LookUpTableB WHERE userID = #userID)
SELECT * FROM Chained_Database2.dbo.ATable
ELSE
SELECT 'User Not Valid'
GO
Note that this assumes the user would only be in one of the look up tables. If they were in both you'd need to handle it differently.
Hi I have a database with a couple of schemas one of which has a Table TABLE_NAME. I need to make a change to the table and to do that I could do with knowing which tables and views in all the different schemas depend on it.
Its an oracle database, is there some SQL I can run that would help?
I've seen a couple of posts that suggest:
select OWNER, Name
from dba_dependencies
where type = 'VIEW'
and REFERENCED_TYPE = 'TABLE'
AND REFERENCED_NAME IN ('table_name', 'TABLE_NAME');
and
select *
from all_constraints
where r_constraint_name in (select constraint_name
from all_constraints
where table_name='TABLE_NAME')
Neither of which appear to be working, the first gives me a "table or view does not exist" on dba_dependencies and the second returns no results.
I have a sql server database which contains 7000 tables and every table ends with a date. I need to find out all the tables of a particular date.
I have the table names as follows:
HouseKeeping_Stage1_12_6_14,
HouseKeeping_Stage1_13_6_14,
HouseKeeping_Stage1_14_6_14,
HouseKeeping_Stage2_12_6_14,
HouseKeeping_Stage2_13_6_14
I want to find out all the records which are associated with the date 12_6_14.
Please let me know how to write the query.
Using SSMS Object Explorer, right-click on the Tables node and select Filter-->Filter Settings. The list will be filtered accordingly.
Alternatively, you can query the catalog or INFORMATION_SCHEMA views:
SELECT
OBJECT_SCHEMA_NAME(object_id) AS schema_name
, name
FROM sys.tables
WHERE name LIKE '%[_]13[_]6[_]14%';
SELECT
TABLE_SCHEMA
, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '%[_]13[_]6[_]14%';
This should do the trick:
SELECT * FROM information_schema.tables
where table_name like '%12_6_14%'
Here is an example: http://sqlfiddle.com/#!6/304bd/1/0
When releasing database code to non-development databases , I use such approach - I create release sqlplus script that runs multiple create table/view/sequence/package/etc statements in a sequence. I also should create rollback script which performs drop and other statements if would be needed during deployment or further use. But it is quite annoying always to create rollback scripts manually. I.E. - when I put
alter table table_a add column some_column number(5);
into release script. I have to put
alter table table_a drop column some_column;
into the rollback script. And vice-versa.
Is there way to optimize(or semi-optimize) it? Maybe some there are some Java/Python/etc libraries that allow to parse ddl statements into logical parts?
Maybe there are some better approaches for release/rollback pl/sql code?
DBMS_METADATA_DIFF and a few metadata queries can automate this process.
This example demonstrates 6 types of changes: 1) adding a column 2) incrementing a sequence 3) dropping a table 4) creating a table 5) changing a view 6) allocating an extent.
create table user1.add_column(id number);
create table user2.add_column(id number);
alter table user2.add_column add some_column number(5);
create sequence user1.increment_sequence nocache;
select user1.increment_sequence.nextval from dual;
select user1.increment_sequence.nextval from dual;
create sequence user2.increment_sequence nocache;
select user2.increment_sequence.nextval from dual;
create table user1.drop_table(id number);
create table user2.create_table(id number);
create view user1.change_view as select 1 a from dual;
create view user2.change_view as select 2 a from dual;
create table user1.allocate_extent(id number);
create table user2.allocate_extent(id number);
insert into user2.allocate_extent values(1);
rollback;
You are correct that DBMS_METADATA_DIFF does not work for CREATE or DROP. Trying to diff an object that only exists in one schema will generate an error message
like this:
ORA-31603: object "EXTRA_TABLE" of type TABLE not found in schema "USER1"
ORA-06512: at "SYS.DBMS_METADATA", line 7944
ORA-06512: at "SYS.DBMS_METADATA_DIFF", line 712
However, dropping and adding objects may be easy to script with the following:
--Dropped objects
select 'DROP '||object_type||' USER1.'||object_name v_sql
from
(
select object_name, object_type from dba_objects where owner = 'USER1'
minus
select object_name, object_type from dba_objects where owner = 'USER2'
);
V_SQL
-----
DROP TABLE USER1.DROPPED_TABLE
--Added objects
select dbms_metadata.get_ddl(object_type, object_name, 'USER2') v_sql
from
(
select object_name, object_type from dba_objects where owner = 'USER2'
minus
select object_name, object_type from dba_objects where owner = 'USER1'
);
V_SQL
-----
CREATE TABLE "USER2"."CREATED_TABLE"
( "ID" NUMBER
) SEGMENT CREATION DEFERRED
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
TABLESPACE "USERS"
The alters can be handled with a SQL statement like this:
select object_name, object_type, dbms_metadata_diff.compare_alter(
object_type => object_type,
name1 => object_name,
name2 => object_name,
schema1 => 'USER2',
schema2 => 'USER1',
network_link1 => 'MYSELF',
network_link2 => 'MYSELF') difference
from
(
select object_name, object_type from dba_objects where owner = 'USER1'
intersect
select object_name, object_type from dba_objects where owner = 'USER2'
) objects;
OBJECT_NAME OBJECT_TYPE DIFFERENCE
----------- ----------- ----------
ADD_COLUMN TABLE ALTER TABLE "USER2"."ADD_COLUMN" DROP ("SOME_COLUMN")
ALLOCATE_EXTENT TABLE -- ORA-39278: Cannot alter table with segments to segment creation deferred.
CHANGE_VIEW VIEW -- ORA-39308: Cannot alter attribute of view: SUBQUERY
INCREMENT_SEQUENCE SEQUENCE ALTER SEQUENCE "USER2"."INCREMENT_SEQUENCE" RESTART START WITH 3
Some notes about these results:
ADD_COLUMN works as expected.
ALLOCATE_EXTENT is probably a false positive, I doubt you care about deferred segment creation. It is very unlikely to affect your system.
CHANGE_VIEW does not work at all. But as with the previous metadata queries, there should be a relatively easy way to build this script using DBA_VIEWS.
INCREMENT_SEQUENCE works too well. Most of the time an application does not care about the sequence values. But sometimes when things get out of sync you need to change them. This RESTART START WITH syntax can be very helpful. You don't need to drop or re-create the indexes, or mess with the increment by multiple times. This syntax is not in the 12c manual. In fact, I cannot find it anywhere on Google. Looks like this package is using undocumented features.
Some other notes:
The package can be very slow sometimes.
If network links on the server are a problem you will need to run it through a local instance with links to both servers.
There may be false positives. Sometimes it returns a row with just a space in it.
It is possible to fully automate this process. But based on the issues above, and my experience with all such automated tools, you should not trust it 100%.
I have a special case,
for example in table ta in database A, it stores all the products I buy
table ta(
id,
name,
price
)
in table tb in database B, it contain all the product that people can buy
table tb(
id,
name,
price
....
)
Can I create a view in database A to list all the products that I haven`t bought?
Yes you can - the t-sql syntax is the same as within any other cross database call (within a stored procedure for example).
To reference your tables in the second database you simply need:
[DatabaseName].[Schema].[TableName]
So you would end up with something like
CREATE VIEW [dbo].[YourView]
as
select
a.ID,
a.SomeInfo,
b.SomeOtherInfo
from TableInA a
join DatabaseB.dbo.TableInB b
on -- your join logic goes here
Note that this will only work on the same server - if your databases are on different servers them you will need to create a linked server.
As the other answers indicate, you can use the {LINKED_SERVER.}DATABASE.SCHEMA.OBJECT notation.
You should also be aware that cross-database ownership chaining is disabled by default.
So within a database, granting SELECT on a view allows a user who may not have SELECT on the underlying tables to still SELECT from the view. This may not work across to another database where the user does not have permissions on the underlying table.
Yes, views can reference three part named objects:
create view A.dbo.viewname as
select ... from A.dbo.ta as ta
join B.dbo.tb as tb on ta.id = tb.id
where ...
There will be problems down the road with cross db queries because of backup/restore consistency, referential integrity problems and possibly mirorring failover, but those problems are inherent in having the data split across dbs.