How to create UDF in Azure synapse with column as input parameter and return a table? - select

I have a select query which need to converted to UDF in Azure Synapse.
Declare #periodstring = '(''2007-08-09'', ''2009-08-25'')'
select FIRST_VALUE(case when ordinal=1 then cast(replace(replace(value, '(''', ''), '''', '') as DATETIME2) end) over (partition by #periodstring order by #periodstring) as startdate,
LAST_VALUE(case when ordinal=2 then cast(replace(replace(value, ''')', ''), '''', '') as DATETIME2) end) over (partition by #periodstring order by #periodstring) as enddate
FROM STRING_SPLIT(#periodstring, ',', 1)
Want to create a UDF which takes table column as input parameter and return a table or datettime columns as output.
How to go ahead with this or is there any other way to handle this??

Azure Synapse Analytics, dedicated SQL pools support scalar functions, inline table-valued functions not multi-statement functions. Read about both scalar and inline table-valued functions with Synapse here and give it a try.

Related

How to combine multiple tables together in postgresql that have the same columns but in different order?

I have multiple tables that all have the same columns, but in different order. I want to merge them all together. I've created an empty table with the standard columns in the order I would like. I've tried inserting with
insert into master_table select * from table1;
but that doesn't work because of the differing column order - some of the values end up in the wrong columns. What is the best way to create one table out of them all in the order specified in my empty master table?
If you are dealing with many columns and many tables, you can use the information_schema to get the columns. You can loop through all the tables you want to insert from and run this in a plpgsql procedure, replacing table1 with a variable:
EXECUTE (
SELECT
'insert into master_table
(' || string_agg(quote_ident(column_name), ',') || ')
SELECT ' || string_agg('p.' || quote_ident(column_name), ',') || '
FROM table1 p '
FROM information_schema.columns raw
WHERE table_name = 'master_table');
just indicate the proper order in the select
instead of
select *
if you want 3 field on second posiition.
select field1, field3, field2
or you can use the INSERT sintaxis
INSERT INTO master_table (field1, field3, field2)
SELECT *

DB2 Query issue

SELECT
Q."COLUMN1"
FROM
(SELECT
"COLUMN1",
CAST ((SELECT CAST (RTRIM (PARAM) AS VARCHAR(50)) FROM TABLE_VIEW WHERE PARAM_ID = :ID) AS VARCHAR(50)) AS "COLUMN2"
FROM ("TABLE1")Q
WHERE
RTRIM(CAST("COLUMN1" AS CHAR(10))) IN (SELECT VALUE_1 FROM TABLE (SPLIT_PARAMS(CAST(Q."COLUMN2" AS VARCHAR(50)),',',5)))
COLUMN2 gets its value from a separate table based on the input provided at run time.
The filter used in the query consists of a used defined table valued function that is used to split the comma separated valued to individual values.
The query throws the error message as:
"FUNCTION NOT SUPPORTED. SQLCODE=-270, SQLSTATE=42997"
Can anyone help me find the cause of the issue.

Oracle convertion to sql for DECODE

Hi all I have query in oracle as follows
DECLARE in_variable Varchar;
Select Row_Number()
OVER
(
Order By
Decode(in_variable,'column_name ASC',t.column_name) Asc) b
From table t
Converted to sql server as follows
DECLARE #in_variable NVARCHAR(100)
SELECT ROW_NUMBER() OVER
(
ORDER BY
IIF ( #in_sort_by <> '', 'column_name ASC', t.column_name ) ASC )
FROM table t
Is it the correct one or am I doing wrong when I give the value for #in_variable I am getting conversion exception in sql so can some one help me
Rather than using either DECODE or IIF, you'd be better of using CASE. For SQL Server, this would be:
SELECT ROW_NUMBER() OVER
( ORDER BY
CASE WHEN #in_sort_by <> ''
THEN 'column_name ASC'
ELSE t.column_name END ASC )
FROM table t
If you're getting a type conversion error, that would imply that t.column_name is an int. SQL Server will try to convert the static string 'column_name ASC' to match the data type of the column it is being used in place of. To fix this, you can try using CAST to convert the column to VARCHAR:
SELECT ROW_NUMBER() OVER
( ORDER BY
CASE WHEN #in_sort_by <> ''
THEN 'column_name ASC'
ELSE CAST(t.column_name as varchar) END ASC )
FROM table t
However, I think you're probably pursuing the wrong solution here. It looks like you're trying to make the analytic function sort differently based on the variable provided. Providing the alternate column name and sort order as a string is not going to do that. You should probably look questions related to dynamic sorting for how to do this correctly.

TSQL - Passing fields from table into stored procedure then storing result in temp table

I'm working with a client who has a stored procedure with about a dozen parameters.
I need to get the parameter values from tables in the database, then feed these into the stored procedure to get a number value. I then need to join this value to a SELECT statement.
I know that I have to build a temp table in order to join the SP results with my select statement, but this is all new to me and could use some help. Mostly focusing on how to feed field values into the SP. I would also like the Temp table to contain a couple of the parameters as fields so I can join it to my select statement.
any and all help is appreciated.
Thank You
You can capture the parameter values in declared variables. Something like:
DECLARE #Parm1 int, #Parm2 varchar(50) -- Use appropriate names and datatypes
SELECT #Parm1 = Parm1ColumnName, #Parm2=Parm2ColumnName
FROM TableWithParmValues
-- Include a WHERE condition if appropriate
DECLARE #ProcOutput TABLE(outputvalue int) -- use appropriate names and datatypes to match output
INSERT #ProcOuptut
EXECUTE MyProc #ProcParm1 = #Parm1, #ProcParm2 = #Parm2 -- Use appropriate names
Then use the #ProcOutput temp table, and parameter variables as you need with your SELECT.
This is a comment that is better formatted as an answer.
You don't need to create a temporary table, or table variable, to be able to join a numeric result with other data. The following demonstrates various curiosities using SELECTs without explicitly creating any tables:
declare #Footy as VarChar(16) = 'soccer'
select * from (
select 'a' as Thing, 42 as Thingosity
union all
select *
from ( values ( 'b', 2 ), ( 'c', 3 ), ( #Footy, Len( #Footy ) ) ) as Placeholder ( Thing, Thingosity )
) as Ethel cross join
( select 42 as TheAnswer ) as Fred

How to determine internal name of table-valued variable in MS SQL Server 2005

The name of a temporary table such as #t1 can be determined using
select #TableName = [Name]
from tempdb.sys.tables
where [Object_ID] = object_id('tempDB.dbo.#t1')
How can I find the name of a table valued variable, i.e. one declared by
declare #t2 as table (a int)
the purpose is to be able to get meta-information about the table, using something like
select #Headers = dbo.Concatenate('[' + c.[Name] + ']')
from sys.all_columns c
inner join sys.tables t
on c.object_id = t.object_id
where t.name = #TableName
although for temp tables you have to look in tempdb.sys.tables instead of sys.tables. where do you look for table valued variables?
I realize now that I can't do what I wanted to do, which is write a generic function for formatting table valued variables into html tables. For starters, in sql server 2005 you can't pass table valued parameters:
http://www.sqlteam.com/article/sql-server-2008-table-valued-parameters
moreover, in sql server 2008, the parameters have to be strongly typed, so you will always know the number and type of columns.
Table variable metadata is viewable in tempdb.sys.tables too. This is easily verifiable from the below
declare #t2 as table ( [38F055D8-25D9-4AA6-9571-F436FE] int)
SELECT t.name, t.object_id
FROM tempdb.sys.tables t
JOIN tempdb.sys.columns c
ON t.object_id = c.object_id
WHERE c.name = '38F055D8-25D9-4AA6-9571-F436FE'
Example Results
name object_id
------------------------------ -----------
#4DB4832C 1303675692
But you will notice the object name is auto generated and bears no relation to the variable name.
If you do not have a guaranteed unique column name that you can use to filter on as above and the table variable has at least one row in it you can (from SQL Server 2008 onwards) use %%physloc%% and DBCC PAGE to determine this information. Example below.
DECLARE #t2 AS TABLE ( a INT)
INSERT INTO #t2
VALUES (1)
DECLARE #DynSQL NVARCHAR(100)
SELECT TOP (1) #DynSQL = 'DBCC PAGE(2,' + CAST(file_id AS VARCHAR) + ',' +
CAST( page_id AS VARCHAR) +
',1) WITH TABLERESULTS'
FROM #t2
CROSS APPLY sys.fn_PhysLocCracker( %% physloc %% )
DECLARE #DBCCPage TABLE (
[ParentObject] [VARCHAR](100) NULL,
[Object] [VARCHAR](100) NULL,
[Field] [VARCHAR](100) NULL,
[VALUE] [VARCHAR](100) NULL )
INSERT INTO #DBCCPage
EXEC (#DynSQL)
SELECT VALUE AS object_id,
OBJECT_NAME(VALUE, 2) AS object_name
FROM #DBCCPage
WHERE Field = 'Metadata: ObjectId'
From Books Online:
A table variable behaves like a local variable. It has a well-defined scope, which is the function, stored procedure, or batch in which it is declared.
Given this, there should be no need to look up this value at run-time because you have to know it at design-time.
I don't believe you can, as table variables are created in memory not in tempdb.
On the topic of passing arbitrary lists/arrays into a SQL Server 2005 function or sproc, the least hokey way I know is to use an XML variable. If desired, that XML variable can be a strongly typed XML type that is associated w/ an XML Schema.
Given a list passed into a procedure/function as XML, you can extract that list into a table variable or temp table via "shredding".
"To shred" XML means to transform in the opposite direction--from XML to rowset(s). (The FOR XML clause causes a rowset to XML transformation.)
In the user-defined table function
CREATE FUNCTION [dbo].[udtShredXmlInputBondIdList]
(
-- Add the parameters for the function here
#xmlInputBondIdList xml
)
RETURNS
#tblResults TABLE
(
-- Add the column definitions for the TABLE variable here
BondId int
)
AS
BEGIN
-- Should add a schema validation for #xmlInputIssuerIdList here
--Place validation here
-- Fill the table variable with the rows for your result set
INSERT #tblResults
SELECT
nref.value('.', 'int') as BondId
FROM
#xmlInputBondIdList.nodes('//BondID') as R(nref)
RETURN
END
if the #xmlInputBondIdList is an XML fragment of the expected structure like that immediately below and is invoked as follows
DECLARE #xmlInputBondIdList xml
SET #xmlInputBondIdList =
'<XmlInputBondIdList>
<BondID>8681</BondID>
<BondID>8680</BondID>
<BondID>8684</BondID>
</XmlInputBondIdList>
'
SELECT *
FROM [CorporateBond].[dbo].[udtShredXmlInputBondIdList]
(#xmlInputBondIdList)
the result will be the rowset
BondId
8681
8680
8684
A couple other examples can be found at http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=678284&SiteID=1