How to use SAS data set brought to SQL Server temporary table and use with another temp table to join,update - sql

Using SAS Enterprise Guide Version 7.1 64 bit.
I cannot create base tables in SQL Server thus can only create temporary table for data processing.
I am also pulling data over from a SAS data set to a global temporary table as(the SAS data set is teradata table pushed to sas-(step2). I need to update holiday table.
I also cannot see how many records are updated in the log (if there is a way to get it, it will be helpful as that way i know the code is working) - I have the sastraceloc but that is not showing update counts in a table.
I finally need to update ##t1 (step4) table created in step 1 with fields from ##holidays table (step2), how do I code this? Am I using the execute, proc sql combination correctly?
Step #1
LIBNAME tmpdta ODBC DATAsrc=datasrcname INSERTBUFF=32767
USER='uid' PASSWORD="pwd" connection=shared;
LIBNAME loc '/c/folder/data';
PROC SQL exec noerrorstop;
CONNECT TO odbc as test(DSN=datasrcname USER='uid' PASSWORD="pwd" connection=shared;
connection=shared);
execute
(create table ##t1
id int,
name varchar(50),
address varchar(100)
)by test;
-- end of 1
step #2
data tmpdt.'##holidays'n;
set loc.holidayexpns;
run;
step #3
proc sql;
connect using tmpdt;
execute
(
update u SET
fee=0,
month=5
FROM tmpdt.##holidays u
)by tmpdt;
step #4
PROC SQL exec noerrorstop;
CONNECT TO odbc as test(DSN=datasrcname USER='uid' PASSWORD="pwd" connection=shared;
connection=shared);
execute
(
update xyz
set a.fee=b.fee,
a.month=b.month
from tmpdt.##holidays h
join ##t1 xyz on
h.id=xyz.id
)by test;

The execute native-query will not know the SAS reference tmpdt., tmpdt will be known to your user login only if on the SQL Server side you have access to a catalog of like name. Did you mean to indicate tempdb ?
Per documentation
Any return code or message that is generated by the DBMS is available in the macro variables SQLXRC and SQLXMSG after the statement completes.

Related

How to dynamically execute SQL in SAP IQ, to consume in Crystal Reports

Goal:
I have a stored procedure in SAP IQ that uses execute() to execute a dynamic SQL statement into a temp table, and then it selects from the table as the output.
Problem:
The proc returns the appropriate dataset just fine in my SQL client, but when I try to execute it in Crystal Reports, it does not return any columns, and instead returns a column named "expression". I believe this is Crystal's way of indicating that it couldn't interpret the result set.
Question:
What is the correct way to dynamically execute a query in IQ? Particularly in terms of executing the proc via Crystal Reports. I'm used to working in SAP ASE, and this is a procedure that I'm attempting to move from ASE to IQ.
Reproducible example:
/* Example proc that create a temp table with a dynamic value */
create or replace proc test_exec (
#num_value int
)
as
begin
-- Dynamically create the temp table with the requested column value
execute('select ' || #num_value || ' as column_1 into #temp')
-- Return the result
select column_1 from #temp
end
Output from the SQL client (correct):
exec test_exec 123
column_1
123
Output in Crystal Reports (does not return column_1):
This is likely due to a difference in the driver used to connect. The query tool is using a built in JDBC driver, while Crystal is using a different driver for its ODBC connection.
I cannot tinker the ODBC settings on this work computer, so I can't experiment with different settings to give a definitive answer of the cause.

Stored Procedure Select data from Server A and Insert data to Server B

I would like to ask about how to write the Stored Procedure Select data from Server A and Insert data to Server B?
1 . Create a linked server using steps at below link
https://www.sqlshack.com/how-to-create-and-configure-a-linked-server-in-sql-server-management-studio/
Create a synonym for the table from the linked server you are going to use if there is only one table otherwise create synonym for that server so you dont have to use the complete name and if the server changes in future you dont have to go and change in every procedure instead you can just change the synonym.
CREATE SYNONYM MySyn
FOR LinkedServerName.DatabaseName.SchemaName;
GO
Use the synonym in your query to fetch the data.
create procedure procedureName
as
begin
insert into destDB.schema.tablename select * from mysyn.sourcetablename
end

How to redirect a request for DB1 to DB2

Suppose I have two databases named DB1 and DB2. In DB1, there is a table named Student, In DB2, there is a stored procedure named SP1. In SP1, I am selecting data of Student Table using below query :
Select *from DB1.dbo.Student.
I have more than 300 stored procedures having above said cross database communication. Now, I want to change my database from DB1 to DB3 that is identical to DB1 from data and schema perspective.
For this, I also have to modify all 300 stored procedures that are having fully-qualified database name. Now, the query will likely to be as follows :
Select *from DB3.dbo.Student
I don't want to change all stored procedure to point DB3 now, also don't want to change my queries written in stored procedure into dynamic SQL (I know this can be done by creating dynamic SQL).
Is it possible if We run DB1.dbo.Student, It will redirect to DB3.dbo.Student. Any intermediate layer or any SQL setting.
It'll be very big help for me. Thanks In Advance !!
If the purpose of your database renaming is to migrate a database, then why not rename the databases themselves?
e.g. say rename DB1 to DB1_old and then rename DB3 to DB1
I would simply script out all stored procedures using SQL Server script generator tool. Then do a find replace on the script and find text ‘DB1.dbo.’ and replace with ‘DB3.dbo.’
In the future you might want to consider using synonyms to reference external tables then you would only have to update the synonyms instead of all of your procedures. Please see following MSDN article on synonyms:
https://msdn.microsoft.com/en-us/library/ms187552.aspx
Example use of synonym:
USE [DB1]
GO
-- Create a synonym for table A located in DB2.
CREATE SYNONYM [dbo].[External_TableA] FOR [DB2].[dbo].[TableA]
GO
-- Synonym is pointing to TableA in DB2 , select statement will return data from DB2 tabla A.
SELECT *
FROM [External_TableA]
GO
-- Point the Synonym to same table but on DB3
DROP SYNONYM [dbo].[External_TableA]
CREATE SYNONYM [dbo].[External_TableA] FOR [DB3].[dbo].[TableA]
GO
-- No update was needed on views or stored procedure.
-- Synonym is pointing to TableA in DB3 , select statement will return data from DB3 tabla A.
SELECT *
FROM [External_TableA]
The follow query will generate the required DROP and CREATE script to remap your synonyms from the old database to the new database.
DECLARE #oldDB NVARCHAR(100) = 'DB2';
DECLARE #newDB NVARCHAR(100) = 'DB3';
SELECT 'DROP SYNONYM [dbo].[' + name + ']' AS [Drop Script]
,'CREATE SYNONYM [dbo].[' + name + '] FOR ' + REPLACE(base_object_name, #oldDB, #newDB) AS CreateScript
FROM sys.synonyms
ORDER BY name
its better to use USE Keyword
use [database name you want to access]
Queries and stored procedure you want to use
GO
eg
use [db1]
select *from yourTableName
exec yourStoredProcedure parm1,parm2,....
Go

Passing temp table from one execution to another

I want to pass a temp table from one execution path to another one nested in side it
What I have tried is this:
DECLARE #SQLQuery AS NVARCHAR(MAX)
SET #SQLQuery = '
--populate #tempTable with values
EXECUTE('SELECT TOP (100) * FROM ' + tempdb..#tempTable)
EXECUTE sp_executesql #SQLQuery
but it fails with this error message:
Incorrect syntax near 'tempdb'
Is there a another\better way to pass temporary table between execution contexts?
You can create a global temp table using the ##tablename syntax (double hash). The difference is explained on the TechNet site:
There are two types of temporary tables: local and global. They differ from each other in their names, their visibility, and their availability. Local temporary tables have a single number sign (#) as the first character of their names; they are visible only to the current connection for the user, and they are deleted when the user disconnects from the instance of SQL Server. Global temporary tables have two number signs (##) as the first characters of their names; they are visible to any user after they are created, and they are deleted when all users referencing the table disconnect from the instance of SQL Server.
For example, if you create the table employees, the table can be used by any person who has the security permissions in the database to use it, until the table is deleted. If a database session creates the local temporary table #employees, only the session can work with the table, and it is deleted when the session disconnects. If you create the global temporary table ##employees, any user in the database can work with this table. If no other user works with this table after you create it, the table is deleted when you disconnect. If another user works with the table after you create it, SQL Server deletes it after you disconnect and after all other sessions are no longer actively using it.
If a temporary table is created with a named constraint and the temporary table is created within the scope of a user-defined transaction, only one user at a time can execute the statement that creates the temp table. For example, if a stored procedure creates a temporary table with a named primary key constraint, the stored procedure cannot be executed simultaneously by multiple users.
The next suggestion may be even more helpful:
Many uses of temporary tables can be replaced with variables that have the table data type. For more information about using table variables, see table (Transact-SQL).
Your temp table will be visible inside the dynamic sql with no problem. I am not sure if you are creating the temp table inside the dynamic sql or before.
Here it is with the table created BEFORE the dynamic sql.
create table #Temp(SomeValue varchar(10))
insert #Temp select 'made it'
exec sp_executesql N'select * from #Temp'
The reason for your syntax error is that you are doing an unnecessary EXECUTE inside an EXECUTE, and you didn't escape the nested single-quote. This would be the correct way to write it:
SET #SQLQuery='
--populate #tempTable with values
SELECT TOP 100 * FROM tempdb..#tempTable'
However, I have a feeling that the syntax error is only the beginning of your problems. Impossible to tell what you're ultimately trying to do here, only seeing this much of the code, though.
Your quotations are messed up. Try:
SET #SQLQuery='
--populate #tempTable with values
EXECUTE(''SELECT TOP 100 * FROM '' + tempdb..#tempTable + '') '

How to execute sql query when debugging a stored procedure

I'm debugging a stored procedure on SQL Server 2008 and I have this:
INSERT INTO #tempTable (ID, Name)
SELECT ID, Name FROM dbo.MYTABLE WHERE dbo.MYTABLE.Old >= 15
How can I view the data into #tempTable on Debug time?
In SQL Server Management Studio, you can't execute query directly while debugging stored procedure, and that's still not implemented(I think). You can only view the local variables value in Local Debug Window.
There are some work around to see temp table values while in Debugging mode:-
1) In the stored procedure, after insert data into #temptable, add this line of code to get temptable values in xml table varriable where you want to see temptable values. Then you can check the values in Local Debug window in xml format
--inserting data into temp table
INSERT INTO #tempTable (ID, Name)
SELECT ID, Name FROM dbo.MYTABLE WHERE dbo.MYTABLE.Old >= 15
--to see records of temp table
DECLARE #temptable XML
SET #temptable = (SELECT * FROM ##temptable FOR XML AUTO)
2) You can convert local temp table(#temptable) to global temptable(##temptable), so when you insert date in temp table, you can open new query window, and able to see global temp table records using select query.
This blog post describes how to access a temporary table from another session:
http://web.archive.org/web/20180409190701/http://sqlblog.com:80/blogs/paul_white/archive/2010/08/14/viewing-another-session-s-temporary-table.aspx
Alternative you can use two ## in the table name to make the table globally accessible from other sessions: ##tempTable (The table might be locked for reading while your insert is running)
Even though SQL Server Management Studio has some debugging functions , but I find them pretty useless.
I don't think there are any debugging tools out there for SQL Server like Visual Studio, which will give you a step by step information at runtime.
The way normally developers debug sql server code is to use print statement, for stored procedures take the sp definition out declare a variable for each parameter that procedure expects , hardcode the values for variables and execute smaller logical blocks of code to see what's going on where.