SSIS OLEDB Dataflow Source using temp table but with Stored Procedured - tsql

SET NOCOUNT ON
SET FMTONLY OFF
IF OBJECT_ID('tempdb..#Temp')is not null
drop table ##Temp
select * into #Temp
FROM dbo.employee
SELECT * FROM #Temp
-- failed to map the column. error pops up saying .. No column is return. But if I use Stored Procedure then it would return using
SET NOCOUNT ON
SET FMTONLY OFF

Related

Can't create Postgres procedure from a query

I am coming from a mssql world and moving over to postgres. I am trying to create a new procedure from a query I wrote and it fails on creation. I am using pgAdmin 4 to create the proc and I've tried copy-pasting the query into the "code" tab of the dialog box.
What I'm trying to accomplish is inserting a bunch of rows into a table and outputting the ids from the identity column into a temporary table. I will be using those ids for more work further down the line, but it's failing before it is even usable. The way I did it in MSSQL was I had a table variable and used "output inserted.id" to get those values to insert into the table variable.
From what I understand, I have to create a temp table and use the returning keyword in postgres. The following query works if I run it in a query window
CREATE TEMPORARY TABLE temp_table
(
temp_id integer
);
WITH ROWS AS
(
INSERT INTO table_a
(some_name_a)
SELECT some_name_b
FROM table_b
RETURNING id)
INSERT INTO temp_table(temp_id)
SELECT id FROM ROWS;
But when I try to create the procedure for that I get an error saying
"ERROR: syntax error at or near "CREATE" LINE 3: AS $BODY$CREATE TEMPORARY TABLE temp_table^"
Here is what the create proc code looks like:
CREATE OR REPLACE PROCEDURE public.temp()
LANGUAGE 'plpgsql'
AS $BODY$
CREATE TEMPORARY TABLE temp_table
(
temp_id integer
);
WITH ROWS AS
(
INSERT INTO table_a
(some_name_a)
SELECT some_name_b
FROM table_b
RETURNING id)
INSERT INTO temp_table(temp_id)
SELECT id FROM ROWS;
$BODY$;

How to insert dynamic sql result into temp table without knowing the columns in advance

I am trying to insert result of dynamic sql into temp table. Important thing is i dont know the column names in advance. As per the SO suggestion the following should work
INSERT into #T1 execute ('execute ' + #SQLString )
also, omit the EXECUTE if the sql string is something other than a procedure.
However this is not working on SQL 2017
CREATE TABLE Documents(DocumentID INT, Status NVARCHAR(10))
INSERT INTO Documents(DocumentID,Status)
VALUES
(1,'Active'),
(2,'Active'),
(3,'Active'),
(4,'Active')
DECLARE #SQLString NVARCHAR(MAX)
SET #SQLString = 'SELECT * FROM Documents'
INSERT into #T1 execute ('execute ' + #SQLString )
I get error `Invalid object name '#T1'.`
Then i tried by omitting execute
INSERT into #T1 execute (#SQLString)
with same error `Invalid object name '#T1'.`
I should be able to do
SELECT * FROM #T1
You cannot do an INSERT INTO without having the table predefined. But what I believe you are asking is to do a SELECT INTO. I am aware of two ways of doing it. The first uses OPENROWSET, but I believe this has some drawbacks for security purposes. You could do the following:
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
GO
SELECT *
INTO #T1
FROM OPENROWSET('SQLNCLI',
'Server=localhost;Trusted_Connection=yes;',
'SELECT * from <YOURDATABASE>.dbo.Documents')
Your second option is to create an inline TVF that will generate the table structure for you. So you could do the following:
CREATE FUNCTION getDocuments()
RETURNS TABLE
AS
RETURN
SELECT * from Documents
GO
SELECT * into #T1 FROM getDocuments()

Import Proc definition from network file with BULK

I'm trying to create 1000+ Procs in MS SQL from supplied physical files as part of legacy migration located on Network . For now I plan to use sp with dynamic SQL to loop over all of them like in segment below, I had problem with BULK ROWTERMINATOR, so I just dummied it with bunch of ZZZZ, is there any other correct way to set it to NONE, so all string will be loaded into single row for run. I also use Nvarchar(Max) for my field.
DROP TABLE IF EXISTS #imp;
CREATE TABLE #imp (Col varchar(max))
BULK INSERT #imp
FROM '//TFSNetwork/log/Install/sp_Test02.sql'
WITH (ROWTERMINATOR = '\nzzzzzzzzzZZZ') ---<< ?????
select top 1 #Sql = Col from #imp
EXEC (#sql);
----------------------------------------------------sp_Test02.sql
CREATE PROCEDURE [dbo].[sp_Test]
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET NOCOUNT ON;
SELECT GETDATE() AS TS
END
-----------------------------------------------------------------
Load whole file into single row/column
ROWTERMINATOR = '\n' is what used by default ,that's why you get it once omitted at all. Don't think we can or will want to change this behavior rather use your Z combo).
Same thing can be done with another BULK , in this case no need any ROWTERM options.
declare #myFile varchar(max)
select #myFile = BulkColumn
from openrowset(BULK '//Network/Path/Test02.sql', single_blob) x;
SELECT #myFile

stored procedures in SQL with result set

EXECUTE the stored procedure - Using EXECUTE command by adding a WITH RESULT SETS statement.
How to write this?
WITH execute_option
CREATE OR ALTER PROCEDURE dbo.a
AS
SELECT Name FROM sys.tables
GO
EXEC dbo.a WITH RESULT SETS
(
(
Name sysname
)
)

Passing table name in sql stored procedure

Is it possible to pass the table name as input parameter to the stored procedure?
For example:
create procedure test
#tablename char(10)
as
begin
select * from #tablename
end
go
I know this does not work. So what is the best way if I want to pass the table name into the stored procedure?
Many thanks
The safest way to do this is via a view.
Create a view which unions all the tables you may wish to access (and which must all have the same column structure), and prefix the rows with the table name.
CREATE VIEW MultiTable
AS
SELECT 'table1' AS TableName, * FROM table1
UNION ALL
SELECT 'table2' AS TableName, * FROM table2
UNION ALL
SELECT 'table3' AS TableName, * FROM table3
Your stored procedure can now filter on the table name:
CREATE PROCEDURE test
#TableName varchar(100)
AS
SELECT * FROM MultiTable WHERE TableName = #TableName
This is safer than using dynamic SQL creation and execution.
You would need to use dynamic SQL, but you need to be aware of potential sql injection risks you open yourself up to as if #tablename contained something dodgy, you could end up in a world of pain.
e.g.
-- basic check to see if a table with this name exists
IF NOT EXISTS(SELECT * FROM sys.tables WHERE name = #tablename)
RETURN
DECLARE #sql NVARCHAR(100)
SET #sql = 'SELECT * FROM ' + QUOTENAME(#tablename)
EXECUTE(#sql)
You need to be very careful with this approach, make sure you don't open up a can of security worms.
My other concern is that you may be trying to make generic data access sprocs which is usually a bad idea. Obviously I don't know your use case.
DECLARE #Name VARCHAR(50)
SET #Name='Company'
EXEC('SELECT * from ' + #Name )
use this way to get record from database.