use temporary table without future grant - snowflake-cloud-data-platform

I would like to get rid of Teamporary tables without having to issue FUTURE GRANT on my schema. The schema "DB_DEV.Schema" is a "WITH MANAGED ACCESS" schema.
But I do not succeed.
Here is the code of my tests.
Case 1
create or replace temporary table DB_DEV.Schema.TempTable as select cast(null as date) Col1 ,cast(null as date) as Col2 from Dual ;
select * from DB_DEV.Schema.TempTable ;
--SQL compilation error: Object 'DB_DEV.Schema."TempTable"' does not exist or not authorized.
Case 2
grant SELECT,INSERT,UPDATE,DELETE,TRUNCATE ON future TABLES IN SCHEMA DB_DEV.Schema to ROLE My_User_Role ;
create or replace temporary table DB_DEV.Schema.TempTable as select cast(null as date) Col1 ,cast(null as date) as Col2 from Dual ;
select * from DB_DEV.Schema.TempTable ;
--it works
Did I miss something or do something wrong?

Related

How do I force a drop temp table command to fully drop the table?

I'm working on a script, just experimenting and developing. A lot of what I do involves temp tables, where I will select ... into #SomeTable from ..., at least in the initial experimentation/early dev stage.
Then I'll look at the results, make some changes, and go again. But to make things a little easier on myself, I also have a drop table if exists #SomeTable, so I can just rerun the code. So far so good. But, if I add a column to the temp table and then try to access it, I get the error Invalid column name 'newColumn'. I can avoid the error by executing JUST the drop statement, and then executing the whole script, but I would rather not have to do that. As I understand it, there is some caching of temp tables that goes on, and I wonder if that's the culprit. In any case, is there any way to fix this?
Edit: Here is a short script demonstrating the problem. Run the script, then uncomment both comments and run it again:
drop table if exists #DemoTable
select column1 = '1'
,column2 = '2'
-- ,column3 = '3'
into #DemoTable
select column1
,column2
-- ,column3
from #DemoTable
In SSMS you can just add a GO statement to separate the code in 2 batches.
This way the drop is executed before the 2nd part of the script is checked for errors.
drop table if exists #DemoTable
GO
select column1 = '1'
,column2 = '2'
-- ,column3 = '3'
into #DemoTable
select column1
,column2
-- ,column3
from #DemoTable
I have tried to follow the steps mentioned in the question.
Please find the following query samples using Northwind Database.
Added a new column to the temp table and also updated it sucessfully.
-- Create the temporary table #temp_Employees from a physical table called 'Employee' in schema 'dbo' in database 'Northwind'
SELECT EmployeeID, FirstName, LastName , BirthDate
INTO #temp_Employees
FROM [Northwind].[dbo].[Employees]
-- SELECT data from temptable '[#temp_Employees]'
SELECT * FROM #temp_Employees;
-- Add a new column '[City]' to table '[#temp_Employees]'
ALTER TABLE #temp_Employees
ADD [City] NVARCHAR(15) NULL
GO
-- SELECT data from temptable '[#temp_Employees]'
SELECT * FROM #temp_Employees;
-- UPDATE the new column '[City]' in the table '[#temp_Employees]'
UPDATE T
SET T.[City]=E.[City]
FROM #temp_Employees T INNER JOIN [Northwind].[dbo].[Employees] E ON T.EmployeeID=E.EmployeeID;
-- SELECT data from temptable '[#temp_Employees]'
SELECT * FROM #temp_Employees;
-- Drop the temptable if it already exists
IF OBJECT_ID('tempDB..#temp_Employees', 'U') IS NOT NULL
DROP TABLE #temp_Employees;
GO
-- SELECT data from temptable '[#temp_Employees]'
SELECT * FROM #temp_Employees;
Thank you.

Invalid Object Name #temp_Table

When I try to execute this code :
insert into myTable
select col1, col2
from #temp_Table
I got this error:
Invalid Object Name #temp_Table
I am writing this code in SAP Business one as a SQL query and the temp table itself is defined already in the same query.
When I only run
select col1, col2
from #temp_Table
it works fine. Only as insert into does not.
Any suggestion what the problem could be?

Record count of a view and its corresponding table does not match without any joins in view SQL Server

I have a view as below in sql server:
use database2
Go
CREATE VIEW view1
AS
WITH date_cte(datecol)
AS (select getdate())
Select Col1,
Col2,
,....
,[Select datecol from date_cte]
FROM database1.schema1.TABLE
on top a table in different database.
The record count of table as well as view using statement
Select count(1) from database1.schema1.TABLE -- 15487212
Select count(1) from database2.schema2.view1 -- 13324921
Does this problem have any solution?
First of all... you definitely should improve your code:
USE database2
Go
CREATE VIEW schema2.view1
AS
SELECT Col1,
Col2,
,....
,getdate()
FROM database1.schema1.TABLE
Why do you use a CTE just for the date? Another thing, which may cause your error. You create a view without defining your schema. Maybe your view is created but in a different schema? I've added schema2 to your CREATE due to the fact your querying schema2 at the end.
By the way. Your select can be improved too:
Select count(*) from database1.schema1.TABLE -- ??
Select count(*) from database2.schema2.view1 -- ???
Actually the issue here was that data was loading into source table while I was running query to count records.
Therefore the count difference was prevailing.
Thanks for your input

In SQL Server, how do I set the next value for an autoincrement field to an arbitrary value like you can in Postgres?

Is it possible to set the next value of an autoincrement field in SQL Server like you can do in Postgres?
For the curious, here's the whole backstory. My company used to use Postgres, which allows you to easily set the next value of an autoincrement field to an arbitrary value.
New company bought old company, and now we're importing Postgres data to SQL Server. Somehow the autoincremented AcctID field on Accounts got set to a 9-digit number even though there are thousands of 8 digit numbers to be had. Apparently someone did this a while back in Postgres for some now unknown reason.
So now in the new SQL Server database, new accounts are having 9-digit account ids, but the client's accounting software can't deal with 9-digit account numbers, so any new accounts they add can't be processed by their accounting department until this gets resolved.
Of course, there are up to 72 different tables which can have dependencies on the AcctID field of Accounts, and the client created about 360 new accounts before they realized the problems involved, so saving that data, truncating the table, and reinserting the data would be an onerous task.
Much better would be to set the autoincrement value of AcctID to the last 8-digit value + 1. Then at least they'd be able to add new accounts while a solution to the 9-digit accounts was being worked on. In fact they claim they only need 3 of the 360 accounts they've added.
So is it possible to reset the autoincrement value of a field in SQL Server like you can do in Postgres?
In SQL Server you can reset an autoincrement column like this:
dbcc checkident ( table_name, RESEED, new_value )
You can check MSDN's documentation about it here.
You can do this too:
CREATE TABLE #myTable
(
ID INT IDENTITY,
abc VARCHAR(20)
)
INSERT INTO #myTable
SELECT 'abc'
UNION ALL
SELECT 'abc'
UNION ALL
SELECT 'abc'
UNION ALL
SELECT 'abc'
UNION ALL
SELECT 'abc'
UNION ALL
SELECT 'abc'
UNION ALL
SELECT 'abc'
UNION ALL
SELECT 'abc'
UNION ALL
SELECT 'cba'
SELECT *
FROM #myTable
-- Jump Identities
SET IDENTITY_INSERT #myTable ON
INSERT INTO #myTable
( id, abc )
VALUES ( 50, 'cbd' )
SELECT *
FROM #myTable
SET IDENTITY_INSERT #myTable OFF
-- Back to contigious
INSERT INTO #myTable
SELECT 'abc'
UNION ALL
SELECT 'abc'
UNION ALL
SELECT 'abc'
UNION ALL
SELECT 'abc'
UNION ALL
SELECT 'abc'
UNION ALL
SELECT 'abc'
UNION ALL
SELECT 'abc'
UNION ALL
SELECT 'abc'
UNION ALL
SELECT 'cba'
SELECT *
FROM #myTable
DROP TABLE #myTable

Create SQL job that verifies daily entry of data into a table?

Writing my first SQL query to run specifically as a SQL Job and I'm a little out of my depth. I have a table within a SQL Server 2005 Database which is populated each day with data from various buildings. To monitor the system better, I am attempting to write a SQL Job that will run a query (or stored procedure) to verify the following:
- At least one row of data appears each day per building
My question has two main parts;
How can I verify that data exists for each building? While there is a "building" column, I'm not sure how to verify each one. I need the query/sp to fail unless all locations have reported it. Do I need to create a control table for the query/sp to compare against? (as the number of building reporting in can change)
How do I make this query fail so that the SQL Job fails? Do I need to wrap it in some sort of error handling code?
Table:
Employee RawDate Building
Bob 2010-07-22 06:04:00.000 2
Sally 2010-07-22 01:00:00.000 9
Jane 2010-07-22 06:04:00.000 12
Alex 2010-07-22 05:54:00.000 EA
Vince 2010-07-22 07:59:00.000 30
Note that the building column has at least one non-numeric value. The range of buildings that report in changes over time, so I would prefer to avoid hard-coding of building values (a table that I can update would be fine).
Should I use a cursor or dynamic SQL to run a looping SELECT statement that checks for each building based on a control table listing each currently active building?
Any help would be appreciated.
Edit: spelling
You could create a stored procedure that checks for missing entries. The procedure could call raiserror to make the job fail. For example:
if OBJECT_ID('CheckBuildingEntries') is null
exec ('create procedure CheckBuildingEntries as select 1')
go
alter procedure CheckBuildingEntries(
#check_date datetime)
as
declare #missing_buildings int
select #missing_buildings = COUNT(*)
from Buildings as b
left join
YourTable as yt
on yt.Building = b.name
and dateadd(dd,0, datediff(dd,0,yt.RawDate)) =
dateadd(dd,0, datediff(dd,0,#check_date))
where yt.Building is null
if #missing_buildings > 0
begin
raiserror('OMG!', 16, 0)
end
go
An example scheduled job running at 4AM to check yesterday's entries:
declare #yesterday datetime
set #yesterday = dateadd(day, -1, GETDATE())
exec CheckBuildingEntries #yesterday
If an entry was missing, the job would fail. You could set it up to send you an email.
Test tables:
create table Buildings (id int identity, name varchar(50))
create table YourTable (Employee varchar(50), RawDate datetime,
Building varchar(50))
insert into Buildings (name)
select '2'
union all select '9'
union all select '12'
union all select 'EA'
union all select '30'
insert into YourTable (Employee, RawDate, Building)
select 'Bob', '2010-07-22 06:04:00.000', '2'
union all select 'Sally', '2010-07-22 01:00:00.000', '9'
union all select 'Jane', '2010-07-22 06:04:00.000', '12'
union all select 'Alex', '2010-07-22 05:54:00.000', 'EA'
union all select 'Vince', '2010-07-22 07:59:00.000', '30'
Recommendations:
Do use a control table for the buildings - you may find that one
already exists, if you use the Object
Explorer in SQL Server Management
Studio
Don't use a cursor or dynamic SQL to run a loop - use set based
commands instead, possibly something
like the following:
SELECT BCT.Building, COUNT(YDT.Building) Build
FROM dbo.BuildingControlTable BCT
LEFT JOIN dbo.YourDataTable YDT
ON BCT.Building = YDT.Building AND
CAST(FLOOR( CAST( GETDATE() AS FLOAT ) - 1 ) AS DATETIME ) =
CAST(FLOOR( CAST( YDT.RawDate AS FLOAT ) ) AS DATETIME )
GROUP BY BCT.Building

Resources