SnowConvert AI – SQL Server – CREATE FUNCTION¶
Übersetzungsreferenz für die benutzerdefinierten Transact-SQL-Funktionen
Applies to
SQL Server
Azure Synapse Analytics
Beschreibung¶
SQL Server unterstützt nur zwei Arten von benutzerdefinierten Funktionen:
Anhand dieser UDFs-Typen ist es möglich, sie nach der inneren Logik in einfach und komplex, zu unterteilen.
Einfache UDFs, gleicht die SQL Server-Syntax mit der Snowflake-Syntax ab. Dieser Typ fügt keine Logik hinzu und führt direkt zum Ergebnis. Diese entsprechen in der Regel den SQL UDFs von Snowflake. SnowConvert unterstützt die Übersetzung von benutzerdefinierten SQL Server-Skalarfunktionen direkt in Snowflake Scripting-UDFs, wenn sie bestimmte Kriterien erfüllen.\ \ Komplexe UDFs, nutzt umfassend eine bestimmte Anweisung (INSERT, DELETE, UPDATE, SET, DECLARE usw.) oder control-of-flow blocks (IF…ELSE, WHILE usw.) und stellt in der Regel eine Nichtübereinstimmung oder einen Verstoß gegenüber der Definition für SQL UDFs von Snowflake dar.
Einschränkungen¶
Transact UDFs haben einige Beschränkungen, die in anderen Datenbank-Engines (wie Oracle und Teradata) nicht vorhanden sind. Diese Beschränkungen helfen bei der Übersetzung, indem sie das Ausmaß der Fehler eingrenzen. Das bedeutet, dass es bestimmte Szenarien gibt, die wir vermeiden sollten.
Hier sind einige der Beschränkungen, die SQL Server für UDFs hat
UDFs können nicht verwendet werden, um Aktionen durchzuführen, die den Zustand der Datenbank verändern
Benutzerdefinierte Funktionen können keine OUTPUT INTO-Klausel enthalten, die eine Tabelle als Ziel hat
Benutzerdefinierte Funktionen können nicht mehrere Resultsets zurückgeben. Verwenden Sie eine gespeicherte Prozedur, wenn Sie mehrere Resultsets zurückgeben müssen.
Die vollständige Liste finden Sie unter diesem Link Benutzerdefinierte Funktionen erstellen (Datenbank-Engine)
INLINE TABLE-VALUED¶
Übersetzungsreferenz zur Konvertierung von Transact-SQL UDF (benutzerdefinierten Funktionen) mit dem TABLE-Rückgabetyp an Snowflake.
Applies to
SQL Server
Azure Synapse Analytics
Beschreibung¶
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Inline-Funktionen mit Tabellenwerten sind Tabellenausdrücke, die Parameter akzeptieren, eine SELECT-Anweisung ausführen und ein TABLE zurückgeben können (SQL Server-Referenz: Erstellen einer Inline-Funktion mit Tabellenwerten).
Transact-Syntax¶
-- Transact-SQL Inline Table-Valued Function Syntax
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name
( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type
[ = default ] [ READONLY ] }
[ ,...n ]
]
)
RETURNS TABLE
[ WITH <function_option> [ ,...n ] ]
[ AS ]
RETURN [ ( ] select_stmt [ ) ]
[ ; ]
Snowflake SQL-Syntax¶
CREATE OR REPLACE FUNCTION <name> ( [ <arguments> ] )
RETURNS TABLE ( <output_col_name> <output_col_type> [, <output_col_name> <output_col_type> ... ] )
AS '<sql_expression>'sql
Beispielhafte Quellcode-Muster¶
Der folgende Abschnitt beschreibt alle möglichen Quelltextmuster, die in dieser Art von CREATE FUNCTION-Syntax vorkommen können.
Für Inline-Funktionen mit Tabellenwerten kann es nur eine Anweisung pro Body geben, die wie folgt aussehen kann:
SELECT-AnweisungAllgemeiner Tabellenausdruck
WITH
Werte direkt aus einer Tabelle auswählen und zurückgeben¶
Dies ist das einfachste Szenario, bei dem Sie einen einfachen Select aus einer Tabelle durchführen und die Werte zurückgeben
Transact-SQL¶
Tabellenwertfunktion mit Inline-Anweisungen¶
CREATE FUNCTION GetDepartmentInfo()
RETURNS TABLE
AS
RETURN
(
SELECT DepartmentID, Name, GroupName
FROM HumanResources.Department
);
GO
SELECT * from GetDepartmentInfo()
Ergebnis¶
DepartmentID |
Name |
GroupName |
|---|---|---|
1 |
Engineering |
Research and Development |
2 |
Tool Design |
Research and Development |
3 |
Sales |
Sales and Marketing |
4 |
Marketing |
Sales and Marketing |
5 |
Purchasing |
Inventory Management |
6 |
Research and Development |
Research and Development |
7 |
Produktion |
Manufacturing |
8 |
Production Control |
Manufacturing |
9 |
Human Resources |
Executive General and Administration |
10 |
Finanzen |
Executive General and Administration |
11 |
Information Services |
Executive General and Administration |
12 |
Document Control |
Quality Assurance |
13 |
Quality Assurance |
Quality Assurance |
14 |
Facilities and Maintenance |
Executive General and Administration |
15 |
Shipping and Receiving |
Inventory Management |
16 |
Executive |
Executive General and Administration |
Snowflake SQL¶
Tabellenwertfunktion mit Inline-Anweisungen¶
CREATE OR REPLACE FUNCTION GetDepartmentInfo ()
RETURNS TABLE(
DepartmentID STRING /*** SSC-FDM-TS0012 - INFORMATION FOR THE COLUMN DepartmentID WAS NOT FOUND. STRING DATATYPE USED TO MATCH CAST AS STRING OPERATION ***/,
Name STRING /*** SSC-FDM-TS0012 - INFORMATION FOR THE COLUMN Name WAS NOT FOUND. STRING DATATYPE USED TO MATCH CAST AS STRING OPERATION ***/,
GroupName STRING /*** SSC-FDM-TS0012 - INFORMATION FOR THE COLUMN GroupName WAS NOT FOUND. STRING DATATYPE USED TO MATCH CAST AS STRING OPERATION ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
AS
$$
SELECT
CAST(DepartmentID AS STRING),
CAST(Name AS STRING),
CAST(GroupName AS STRING)
FROM
HumanResources.Department
$$;
SELECT
*
from
TABLE(GetDepartmentInfo());
Ergebnis¶
DepartmentID |
Name |
GroupName |
|---|---|---|
1 |
Engineering |
Research and Development |
2 |
Tool Design |
Research and Development |
3 |
Sales |
Sales and Marketing |
4 |
Marketing |
Sales and Marketing |
5 |
Purchasing |
Inventory Management |
6 |
Research and Development |
Research and Development |
7 |
Produktion |
Manufacturing |
8 |
Production Control |
Manufacturing |
9 |
Human Resources |
Executive General and Administration |
10 |
Finanzen |
Executive General and Administration |
11 |
Information Services |
Executive General and Administration |
12 |
Document Control |
Quality Assurance |
13 |
Quality Assurance |
Quality Assurance |
14 |
Facilities and Maintenance |
Executive General and Administration |
15 |
Shipping and Receiving |
Inventory Management |
16 |
Executive |
Executive General and Administration |
Wählen Sie Werte aus mehreren Tabellen aus und geben Sie sie zurück, indem Sie Spalten umbenennen und eingebaute Funktionen verwenden¶
Dies ist ein Beispiel für eine Abfrage mit integrierten Funktionen in einer SELECT-Anweisung, die Daten aus verschiedenen Tabellen abruft, Spalten umbenennt und eine Tabelle zurückgibt.
Transact-SQL¶
Tabellenwertfunktion mit Inline-Anweisungen¶
CREATE FUNCTION GetPersonBasicInfo()
RETURNS TABLE
AS
RETURN
(
SELECT TOP (20)
P.PersonType,
P.FirstName,
E.JobTitle,
E.Gender,
YEAR(E.HireDate) as HIREYEAR
FROM
Person.Person P
INNER JOIN
HumanResources.Employee E
ON
P.BusinessEntityID = E.BusinessEntityID
);
GO
SELECT * FROM GetPersonBasicInfo();
Ergebnis¶
PersonType |
FirstName |
JobTitle |
Geschlecht |
HIREYEAR |
|---|---|---|---|---|
EM |
Ken |
Chief Executive Officer |
M |
2009 |
EM |
Terri |
Vice President of Engineering |
F |
2008 |
EM |
Roberto |
Engineering Manager |
M |
2007 |
EM |
Rob |
Senior Tool Designer |
M |
2007 |
EM |
Gail |
Design Engineer |
F |
2008 |
EM |
Jossef |
Design Engineer |
M |
2008 |
EM |
Dylan |
Research and Development Manager |
M |
2009 |
EM |
Diane |
Research and Development Engineer |
F |
2008 |
EM |
Gigi |
Research and Development Engineer |
F |
2009 |
EM |
Michael |
Research and Development Manager |
M |
2009 |
EM |
Ovidiu |
Senior Tool Designer |
M |
2010 |
EM |
Thierry |
Tool Designer |
M |
2007 |
EM |
Janice |
Tool Designer |
F |
2010 |
EM |
Michael |
Senior Design Engineer |
M |
2010 |
EM |
Sharon |
Design Engineer |
F |
2011 |
EM |
David |
Marketing Manager |
M |
2007 |
EM |
Kevin |
Marketing Assistant |
M |
2007 |
EM |
John |
Marketing Specialist |
M |
2011 |
EM |
Maria |
Marketing Assistant |
F |
2011 |
EM |
Wanida |
Marketing Assistant |
F |
2011 |
Snowflake SQL¶
Tabellenwertfunktion mit Inline-Anweisungen¶
CREATE OR REPLACE FUNCTION GetPersonBasicInfo ()
RETURNS TABLE(
PersonType STRING /*** SSC-FDM-TS0012 - INFORMATION FOR THE COLUMN PersonType WAS NOT FOUND. STRING DATATYPE USED TO MATCH CAST AS STRING OPERATION ***/,
FirstName STRING /*** SSC-FDM-TS0012 - INFORMATION FOR THE COLUMN FirstName WAS NOT FOUND. STRING DATATYPE USED TO MATCH CAST AS STRING OPERATION ***/,
JobTitle STRING /*** SSC-FDM-TS0012 - INFORMATION FOR THE COLUMN JobTitle WAS NOT FOUND. STRING DATATYPE USED TO MATCH CAST AS STRING OPERATION ***/,
Gender STRING /*** SSC-FDM-TS0012 - INFORMATION FOR THE COLUMN Gender WAS NOT FOUND. STRING DATATYPE USED TO MATCH CAST AS STRING OPERATION ***/,
HIREYEAR INTEGER
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
AS
$$
SELECT
TOP 20
CAST(P.PersonType AS STRING),
CAST(P.FirstName AS STRING),
CAST(E.JobTitle AS STRING),
CAST(E.Gender AS STRING),
YEAR(E.HireDate :: TIMESTAMP) as HIREYEAR
FROM
Person.Person P
INNER JOIN
HumanResources.Employee E
ON P.BusinessEntityID = E.BusinessEntityID
$$;
SELECT
*
FROM
TABLE(GetPersonBasicInfo());
Ergebnis¶
PersonType |
FirstName |
JobTitle |
Geschlecht |
HIREYEAR |
|---|---|---|---|---|
EM |
Ken |
Chief Executive Officer |
M |
2009 |
EM |
Terri |
Vice President of Engineering |
F |
2008 |
EM |
Roberto |
Engineering Manager |
M |
2007 |
EM |
Rob |
Senior Tool Designer |
M |
2007 |
EM |
Gail |
Design Engineer |
F |
2008 |
EM |
Jossef |
Design Engineer |
M |
2008 |
EM |
Dylan |
Research and Development Manager |
M |
2009 |
EM |
Diane |
Research and Development Engineer |
F |
2008 |
EM |
Gigi |
Research and Development Engineer |
F |
2009 |
EM |
Michael |
Research and Development Manager |
M |
2009 |
EM |
Ovidiu |
Senior Tool Designer |
M |
2010 |
EM |
Thierry |
Tool Designer |
M |
2007 |
EM |
Janice |
Tool Designer |
F |
2010 |
EM |
Michael |
Senior Design Engineer |
M |
2010 |
EM |
Sharon |
Design Engineer |
F |
2011 |
EM |
David |
Marketing Manager |
M |
2007 |
EM |
Kevin |
Marketing Assistant |
M |
2007 |
EM |
John |
Marketing Specialist |
M |
2011 |
EM |
Maria |
Marketing Assistant |
F |
2011 |
EM |
Wanida |
Marketing Assistant |
F |
2011 |
Spalten mit der WITH-Anweisung auswählen¶
Der Body einer Inline-Funktion mit Tabellenwerten kann auch mit einer WITH -Anweisung angegeben werden, wie unten gezeigt.
Transact-SQL¶
Tabellenwertfunktion mit Inline-Anweisungen¶
CREATE FUNCTION GetMaritalStatusByGender
(
@P_Gender nchar(1)
)
RETURNS TABLE
AS
RETURN
(
WITH CTE AS
(
SELECT BusinessEntityID, MaritalStatus, Gender
FROM HumanResources.Employee
where Gender = @P_Gender
)
SELECT
MaritalStatus, Gender, CONCAT(P.FirstName,' ', P.LastName) as Name
FROM
CTE INNER JOIN Person.Person P
ON
CTE.BusinessEntityID = P.BusinessEntityID
);
GO
select * from GetMaritalStatusByGender('F');
Ergebnis¶
MaritalStatus |
Geschlecht |
Name |
|---|---|---|
S |
F |
Terri Duffy |
M |
F |
Gail Erickson |
S |
F |
Diane Margheim |
M |
F |
Gigi Matthew |
M |
F |
Janice Galvin |
M |
F |
Sharon Salavaria |
S |
F |
Mary Dempsey |
M |
F |
Wanida Benshoof |
M |
F |
Mary Gibson |
M |
F |
Jill Williams |
S |
F |
Jo Brown |
M |
F |
Britta Simon |
M |
F |
Margie Shoop |
M |
F |
Rebecca Laszlo |
M |
F |
Suchitra Mohan |
M |
F |
Kim Abercrombie |
S |
F |
JoLynn Dobney |
M |
F |
Nancy Anderson |
M |
F |
Ruth Ellerbrock |
M |
F |
Doris Hartwig |
M |
F |
Diane Glimp |
M |
F |
Bonnie Kearney |
M |
F |
Denise Smith |
S |
F |
Diane Tibbott |
M |
F |
Carole Poland |
M |
F |
Carol Philips |
M |
F |
Merav Netz |
S |
F |
Betsy Stadick |
S |
F |
Danielle Tiedt |
S |
F |
Kimberly Zimmerman |
M |
F |
Elizabeth Keyser |
M |
F |
Mary Baker |
M |
F |
Alice Ciccu |
M |
F |
Linda Moschell |
S |
F |
Angela Barbariol |
S |
F |
Kitti Lertpiriyasuwat |
S |
F |
Susan Eaton |
S |
F |
Kim Ralls |
M |
F |
Nicole Holliday |
S |
F |
Anibal Sousa |
M |
F |
Samantha Smith |
S |
F |
Olinda Turner |
S |
F |
Cynthia Randall |
M |
F |
Sandra Reátegui Alayo |
S |
F |
Linda Randall |
S |
F |
Shelley Dyck |
S |
F |
Laura Steele |
S |
F |
Susan Metters |
S |
F |
Katie McAskill-White |
M |
F |
Barbara Decker |
M |
F |
Yvonne McKay |
S |
F |
Janeth Esteves |
M |
F |
Brenda Diaz |
M |
F |
Lorraine Nay |
M |
F |
Paula Nartker |
S |
F |
Lori Kane |
M |
F |
Kathie Flood |
S |
F |
Belinda Newman |
M |
F |
Karen Berge |
M |
F |
Lori Penor |
M |
F |
Jo Berry |
M |
F |
Laura Norman |
M |
F |
Paula Barreto de Mattos |
M |
F |
Mindy Martin |
M |
F |
Deborah Poe |
S |
F |
Candy Spoon |
M |
F |
Barbara Moreland |
M |
F |
Janet Sheperdigian |
S |
F |
Wendy Kahn |
S |
F |
Sheela Word |
M |
F |
Linda Meisner |
S |
F |
Erin Hagens |
M |
F |
Annette Hill |
S |
F |
Jean Trenary |
S |
F |
Stephanie Conroy |
S |
F |
Karen Berg |
M |
F |
Janaina Bueno |
M |
F |
Linda Mitchell |
S |
F |
Jillian Carson |
S |
F |
Pamela Ansman-Wolfe |
S |
F |
Lynn Tsoflias |
M |
F |
Amy Alberts |
S |
F |
Rachel Valdez |
M |
F |
Jae Pak |
Snowflake SQL¶
Tabellenwertfunktion mit Inline-Anweisungen¶
--** SSC-FDM-0007 - MISSING DEPENDENT OBJECTS "HumanResources.Employee", "Person.Person" **
CREATE OR REPLACE FUNCTION GetMaritalStatusByGender
(P_GENDER STRING
)
RETURNS TABLE(
MaritalStatus STRING /*** SSC-FDM-TS0012 - INFORMATION FOR THE COLUMN MaritalStatus WAS NOT FOUND. STRING DATATYPE USED TO MATCH CAST AS STRING OPERATION ***/,
Gender STRING /*** SSC-FDM-TS0012 - INFORMATION FOR THE COLUMN Gender WAS NOT FOUND. STRING DATATYPE USED TO MATCH CAST AS STRING OPERATION ***/,
Name VARCHAR
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "07/11/2025", "domain": "no-domain-provided" }}'
AS
$$
--** SSC-PRF-TS0001 - PERFORMANCE WARNING - RECURSION FOR CTE NOT CHECKED. MIGHT REQUIRE RECURSIVE KEYWORD **
WITH CTE AS
(
SELECT
BusinessEntityID,
MaritalStatus,
Gender
FROM
HumanResources.Employee
where
Gender = :P_GENDER
)
SELECT
CAST(MaritalStatus AS STRING),
CAST(Gender AS STRING),
CONCAT(P.FirstName,' ', P.LastName) as Name
FROM
CTE
INNER JOIN
Person.Person P
ON CTE.BusinessEntityID = P.BusinessEntityID
$$;
select
*
from
TABLE(GetMaritalStatusByGender('F'));
Ergebnis¶
MaritalStatus |
Geschlecht |
Name |
|---|---|---|
S |
F |
Terri Duffy |
M |
F |
Gail Erickson |
S |
F |
Diane Margheim |
M |
F |
Gigi Matthew |
M |
F |
Janice Galvin |
M |
F |
Sharon Salavaria |
S |
F |
Mary Dempsey |
M |
F |
Wanida Benshoof |
M |
F |
Mary Gibson |
M |
F |
Jill Williams |
S |
F |
Jo Brown |
M |
F |
Britta Simon |
M |
F |
Margie Shoop |
M |
F |
Rebecca Laszlo |
M |
F |
Suchitra Mohan |
M |
F |
Kim Abercrombie |
S |
F |
JoLynn Dobney |
M |
F |
Nancy Anderson |
M |
F |
Ruth Ellerbrock |
M |
F |
Doris Hartwig |
M |
F |
Diane Glimp |
M |
F |
Bonnie Kearney |
M |
F |
Denise Smith |
S |
F |
Diane Tibbott |
M |
F |
Carole Poland |
M |
F |
Carol Philips |
M |
F |
Merav Netz |
S |
F |
Betsy Stadick |
S |
F |
Danielle Tiedt |
S |
F |
Kimberly Zimmerman |
M |
F |
Elizabeth Keyser |
M |
F |
Mary Baker |
M |
F |
Alice Ciccu |
M |
F |
Linda Moschell |
S |
F |
Angela Barbariol |
S |
F |
Kitti Lertpiriyasuwat |
S |
F |
Susan Eaton |
S |
F |
Kim Ralls |
M |
F |
Nicole Holliday |
S |
F |
Anibal Sousa |
M |
F |
Samantha Smith |
S |
F |
Olinda Turner |
S |
F |
Cynthia Randall |
M |
F |
Sandra Reátegui Alayo |
S |
F |
Linda Randall |
S |
F |
Shelley Dyck |
S |
F |
Laura Steele |
S |
F |
Susan Metters |
S |
F |
Katie McAskill-White |
M |
F |
Barbara Decker |
M |
F |
Yvonne McKay |
S |
F |
Janeth Esteves |
M |
F |
Brenda Diaz |
M |
F |
Lorraine Nay |
M |
F |
Paula Nartker |
S |
F |
Lori Kane |
M |
F |
Kathie Flood |
S |
F |
Belinda Newman |
M |
F |
Karen Berge |
M |
F |
Lori Penor |
M |
F |
Jo Berry |
M |
F |
Laura Norman |
M |
F |
Paula Barreto de Mattos |
M |
F |
Mindy Martin |
M |
F |
Deborah Poe |
S |
F |
Candy Spoon |
M |
F |
Barbara Moreland |
M |
F |
Janet Sheperdigian |
S |
F |
Wendy Kahn |
S |
F |
Sheela Word |
M |
F |
Linda Meisner |
S |
F |
Erin Hagens |
M |
F |
Annette Hill |
S |
F |
Jean Trenary |
S |
F |
Stephanie Conroy |
S |
F |
Karen Berg |
M |
F |
Janaina Bueno |
M |
F |
Linda Mitchell |
S |
F |
Jillian Carson |
S |
F |
Pamela Ansman-Wolfe |
S |
F |
Lynn Tsoflias |
M |
F |
Amy Alberts |
S |
F |
Rachel Valdez |
M |
F |
Jae Pak |
Bekannte Probleme¶
Es wurden keine Probleme gefunden
MULTI-STATEMENT TABLE-VALUED¶
Übersetzungsreferenz zur Konvertierung von Transact-SQL UDF (benutzerdefinierten Funktionen) mit dem TABLE-Rückgabetyp an Snowflake.
Applies to
SQL Server
Azure Synapse Analytics
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Bemerkung
Alle Codebeispiele auf dieser Seite wurden noch nicht in SnowConvert AI implementiert. Sie sollten als Referenz dafür interpretiert werden, wie jedes Szenario in Snowflake übersetzt werden soll. Diese Übersetzungen können sich in Zukunft ändern. Einige Teile des Ausgabecodes werden aus Gründen der Übersichtlichkeit weggelassen.
Beschreibung¶
Eine Tabellenwertfunktion mit mehreren Anweisungen ist ähnlich wie eine Tabellenwertfunktion mit Inline-Anweisungen (INLINE TABLE-VALUED). Eine Tabellenwertfunktion mit mehreren Anweisungen kann jedoch mehr als eine Anweisung im Funktions-Body enthalten, wobei die Tabellenspalten im Rückgabetyp angegeben sind und ein BEGIN/END-Block (SQL Server-Sprachreferenz – Erstellen einer Funktion mit Tabellenwerten für mehrere Anweisungen vorhanden ist.
Transact-SQL-Syntax¶
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name
( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type
[ = default ] [READONLY] }
[ ,...n ]
]
)
RETURNS @return_variable TABLE <table_type_definition>
[ WITH <function_option> [ ,...n ] ]
[ AS ]
BEGIN
function_body
RETURN
END
[ ; ]
Snowflake SQL¶
CREATE OR REPLACE FUNCTION <name> ( [ <arguments> ] )
RETURNS TABLE ( <output_col_name> <output_col_type> [, <output_col_name> <output_col_type> ... ] )
AS '<sql_expression>'
Beispielhafte Quellcode-Muster¶
Der folgende Abschnitt beschreibt alle möglichen Quellcodemuster, die in dieser Art von ofCREATE FUNCTION-Syntax auftreten können.
Der Funktions-Body einer Tabellenwertfunktion mit mehreren Anweisungen muss eine SELECT-Anweisung sein. Aus diesem Grund müssen die anderen Anweisungen separat aufgerufen werden.
Werte in eine Tabelle einfügen¶
Fügt eine oder mehrere Zeilen in die Tabelle ein und gibt die Tabelle mit den neuen Werten zurück
Transact-SQL¶
MULTI-STATEMENT TABLE-VALUED¶
CREATE OR ALTER FUNCTION calc_behavioral_segment()
RETURNS @behavioral_segments TABLE (behavioral_segment VARCHAR(50))
AS
BEGIN
DECLARE @col varchar(15)
SET @col = 'Unknown'
INSERT INTO @behavioral_segments
SELECT @col
RETURN
END
SELECT * FROM calc_behavioral_segment();
Ergebnis¶
BEHAVIORAL_SEGMENT |
|---|
Unbekannt |
Snowflake SQL¶
MULTI-STATEMENT TABLE-VALUED¶
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'TABLE VALUED FUNCTIONS' NODE ***/!!!
CREATE OR ALTER FUNCTION calc_behavioral_segment ()
RETURNS BEHAVIORAL_SEGMENTS TABLE (
behavioral_segment VARCHAR(50))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
BEGIN
DECLARE @col varchar(15)
SET @col = 'Unknown'
INSERT INTO @behavioral_segments
SELECT @col
RETURN
END
SELECT * FROM calc_behavioral_segment();;
Ergebnisse¶
BEHAVIORAL_SEGMENT |
|---|
Unbekannt |
Wert entsprechend der IF/ELSE-Anweisung einfügen¶
Fügt entsprechend der Bedingung eine Zeile in die Tabelle ein und gibt die Tabelle mit dem neuen Wert zurück
Transact-SQL¶
MULTI-STATEMENT TABLE-VALUED¶
CREATE OR ALTER FUNCTION odd_or_even_number(@number INT)
RETURNS @numbers TABLE (number_type VARCHAR(15))
AS
BEGIN
IF ((@number % 2) = 0)
BEGIN
INSERT @numbers SELECT 'Even'
END
ELSE
BEGIN
INSERT @numbers SELECT 'Odd'
END
RETURN
END
SELECT * FROM odd_or_even_number(9);
Ergebnis¶
NUMBER_TYPE |
|---|
Ungerade |
Snowflake SQL¶
MULTI-STATEMENT TABLE-VALUED¶
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'TABLE VALUED FUNCTIONS' NODE ***/!!!
CREATE OR ALTER FUNCTION odd_or_even_number (NUMBER INT)
RETURNS NUMBERS TABLE (
number_type VARCHAR(15))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
BEGIN
IF ((@number % 2) = 0)
BEGIN
INSERT @numbers SELECT 'Even'
END
ELSE
BEGIN
INSERT @numbers SELECT 'Odd'
END
RETURN
END
SELECT * FROM odd_or_even_number(9);;
Ergebnis¶
NUMBER_TYPE |
|---|
Ungerade |
Fügt mehrere gemäß der IF/ELSE-Anweisung ein¶
Das folgende Beispiel fügt mehr als einen Wert in die Tabelle ein und mehr als eine Variable wird entsprechend der Bedingung geändert. Gibt die Tabelle mit den neuen Werten zurück
Transact-SQL¶
MULTI-STATEMENT TABLE-VALUED¶
CREATE OR ALTER FUNCTION new_employee_hired(@id VARCHAR (50), @position VARCHAR(50), @experience VARCHAR(15))
RETURNS @new_employee TABLE (id_employee VARCHAR (50), working_from_home BIT, team VARCHAR(15), computer VARCHAR(15))
AS
BEGIN
DECLARE @wfh BIT
DECLARE @team VARCHAR(15)
DECLARE @computer VARCHAR(15)
IF @position = 'DEVELOPER'
BEGIN
SET @team = 'TEAM_1'
SET @computer = 'LAPTOP'
END
IF @position = 'IT'
BEGIN
SET @team = 'TEAM_2'
SET @computer = 'DESKTOP'
END
IF @experience = 'JUNIOR'
BEGIN
SET @wfh = '0'
END
IF @experience = 'SENIOR'
BEGIN
SET @wfh = '1'
END
INSERT INTO @new_employee VALUES (@id, @wfh, @team, @computer)
RETURN
END
SELECT * FROM new_employee_hired('123456789', 'DEVELOPER', 'SENIOR');
Ergebnis¶
ID_EMPLOYEE |
WORKING_FROM_HOME |
TEAM |
COMPUTER |
|---|---|---|---|
123456789 |
1 |
TEAM_1 |
LAPTOP |
Snowflake¶
MULTI-STATEMENT TABLE-VALUED¶
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'TABLE VALUED FUNCTIONS' NODE ***/!!!
CREATE OR ALTER FUNCTION new_employee_hired (ID STRING, POSITION STRING, EXPERIENCE STRING)
RETURNS NEW_EMPLOYEE TABLE (
id_employee VARCHAR(50),
working_from_home BOOLEAN,
team VARCHAR(15),
computer VARCHAR(15))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
BEGIN
DECLARE @wfh BIT
DECLARE @team VARCHAR(15)
DECLARE @computer VARCHAR(15)
IF @position = 'DEVELOPER'
BEGIN
SET @team = 'TEAM_1'
SET @computer = 'LAPTOP'
END
IF @position = 'IT'
BEGIN
SET @team = 'TEAM_2'
SET @computer = 'DESKTOP'
END
IF @experience = 'JUNIOR'
BEGIN
SET @wfh = '0'
END
IF @experience = 'SENIOR'
BEGIN
SET @wfh = '1'
END
INSERT INTO @new_employee VALUES (@id, @wfh, @team, @computer)
RETURN
END
SELECT * FROM new_employee_hired('123456789', 'DEVELOPER', 'SENIOR');;
Ergebnis¶
ID_EMPLOYEE |
WORKING_FROM_HOME |
TEAM |
COMPUTER |
|---|---|---|---|
123456789 |
1 |
TEAM_1 |
LAPTOP |
Warnung
Falls es verschachtelte IF-Anweisungen gibt und mehr als eine Variable in den Anweisungen geändert wird, ist es notwendig, eine gespeicherte Prozedur zu verwenden.
Zuvor eingefügte Werte aktualisieren¶
Aktualisiert die Spaltenwerte der Tabelle im Funktions-Body und gibt ihn mit den neuen Werten zurück.
Transact-SQL¶
MULTI-STATEMENT TABLE-VALUED¶
CREATE OR ALTER FUNCTION get_employees_history()
RETURNS @employee_history TABLE (
department_name NVARCHAR(50),
first_name NVARCHAR(50),
last_name NVARCHAR(50),
start_date DATE,
end_date DATE,
job_title NVARCHAR(50),
months_working INT
)
BEGIN
INSERT INTO @employee_history
SELECT D.name AS department_name, P.first_name, P.last_name, EH.start_date, EH.end_date, E.job_title, 0 FROM Department D
LEFT OUTER JOIN employee_department_history EH
ON D.department_ID = EH.department_ID
INNER JOIN Employee E
ON E.business_entity_ID = EH.business_entity_ID
INNER JOIN Person P
ON P.business_entity_ID = E.business_entity_ID
UPDATE @employee_history
SET
months_working =
CASE WHEN end_date IS NULL THEN DATEDIFF(MONTH, start_date, GETDATE())
ELSE DATEDIFF(MONTH, start_date, end_date)
END
RETURN;
END;
SELECT TOP(10) * FROM get_employees_history();
Ergebnis¶
DEPARTMENT_NAME |
FIRST_NAME |
LAST_NAME |
START_DATE |
END_DATE |
JOB_TITLE |
MONTHS_WORKING |
|---|---|---|---|---|---|---|
Sales |
Syed |
Abbas |
2013-03-14 |
NULL |
Pacific Sales Manager |
106 |
Produktion |
Kim |
Abercrombie |
2010-01-16 |
NULL |
Production Technician – WC60 |
144 |
Quality Assurance |
Hazem |
Abolrous |
2009-02-28 |
NULL |
Quality Assurance Manager |
155 |
Shipping and Receiving |
Pilar |
Ackerman |
2009-01-02 |
NULL |
Shipping and Receiving Supervisor |
156 |
Produktion |
Jay |
Adams |
2009-03-05 |
NULL |
Production Technician – WC60 |
154 |
Information Services |
François |
Ajenstat |
2009-01-17 |
NULL |
Database Administrator |
156 |
Sales |
Amy |
Alberts |
2012-04-16 |
NULL |
European Sales Manager |
117 |
Produktion |
Greg |
Alderson |
2008-12-02 |
NULL |
Production Technician – WC45 |
157 |
Quality Assurance |
Sean |
Alexander |
2008-12-28 |
NULL |
Quality Assurance Technician |
157 |
Facilities and Maintenance |
Gary |
Altman |
2009-12-02 |
NULL |
Facilities Manager |
145 |
Snowflake SQL¶
MULTI-STATEMENT TABLE-VALUED¶
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'TABLE VALUED FUNCTIONS' NODE ***/!!!
CREATE OR ALTER FUNCTION get_employees_history ()
RETURNS EMPLOYEE_HISTORY TABLE (
department_name VARCHAR(50),
first_name VARCHAR(50),
last_name VARCHAR(50),
start_date DATE,
end_date DATE,
job_title VARCHAR(50),
months_working INT
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
BEGIN
INSERT INTO @employee_history
SELECT D.name AS department_name, P.first_name, P.last_name, EH.start_date, EH.end_date, E.job_title, 0 FROM Department D
LEFT OUTER JOIN employee_department_history EH
ON D.department_ID = EH.department_ID
INNER JOIN Employee E
ON E.business_entity_ID = EH.business_entity_ID
INNER JOIN Person P
ON P.business_entity_ID = E.business_entity_ID
UPDATE @employee_history
SET
months_working =
CASE WHEN end_date IS NULL THEN DATEDIFF(MONTH, start_date, GETDATE())
ELSE DATEDIFF(MONTH, start_date, end_date)
END
RETURN;
END;
SELECT TOP(10) * FROM get_employees_history();;
Ergebnis¶
DEPARTMENT_NAME |
FIRST_NAME |
LAST_NAME |
START_DATE |
END_DATE |
JOB_TITLE |
MONTHS_WORKING |
|---|---|---|---|---|---|---|
Sales |
Syed |
Abbas |
2013-03-14 |
NULL |
Pacific Sales Manager |
106 |
Produktion |
Kim |
Abercrombie |
2010-01-16 |
NULL |
Production Technician – WC60 |
144 |
Quality Assurance |
Hazem |
Abolrous |
2009-02-28 |
NULL |
Quality Assurance Manager |
155 |
Shipping and Receiving |
Pilar |
Ackerman |
2009-01-02 |
NULL |
Shipping and Receiving Supervisor |
156 |
Produktion |
Jay |
Adams |
2009-03-05 |
NULL |
Production Technician – WC60 |
154 |
Information Services |
François |
Ajenstat |
2009-01-17 |
NULL |
Database Administrator |
156 |
Sales |
Amy |
Alberts |
2012-04-16 |
NULL |
European Sales Manager |
117 |
Produktion |
Greg |
Alderson |
2008-12-02 |
NULL |
Production Technician – WC45 |
157 |
Quality Assurance |
Sean |
Alexander |
2008-12-28 |
NULL |
Quality Assurance Technician |
157 |
Facilities and Maintenance |
Gary |
Altman |
2009-12-02 |
NULL |
Facilities Manager |
145 |
Mehrere RETURN-Klauseln¶
Im folgenden Beispiel gibt es mehr als eine Klausel, da es je nach Situation nicht notwendig ist, die gesamte Funktion auszuführen.
Transact-SQL¶
MULTI-STATEMENT TABLE-VALUED¶
CREATE OR ALTER FUNCTIONcreate_new_team(@team_name VARCHAR(50))
</strong>RETURNS @new_team TABLE (type VARCHAR(50), name VARCHAR(50))
AS
BEGIN
DECLARE @employees INT
SET @employees = (SELECT count(*) FROM employee)
DECLARE @type VARCHAR(15)
SET @type = 'small_team'
IF (@employees < 8)
BEGIN
INSERT @new_team VALUES (@type, @team_name)
RETURN
END
SET @type = 'big_team'
INSERT @new_team VALUES (@type, @team_name)
RETURN
END
SELECT * FROMcreate_new_team('Team1');
Ergebnis¶
TYPE |
NAME |
|---|---|
SMALL_TEAM |
TEAM1 |
Snowflake SQL¶
MULTI-STATEMENT TABLE-VALUED¶
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'TABLE VALUED FUNCTIONS' NODE ***/!!!
CREATE OR ALTER FUNCTIONcreate_new_team (TEAM_NAME STRING)
RETURNS NEW_TEAM TABLE (
type VARCHAR(50),
name VARCHAR(50))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
BEGIN
DECLARE @employees INT
SET @employees = (SELECT count(*) FROM employee)
DECLARE @type VARCHAR(15)
SET @type = 'small_team'
IF (@employees < 8)
BEGIN
INSERT @new_team VALUES (@type, @team_name)
RETURN
END
SET @type = 'big_team'
INSERT @new_team VALUES (@type, @team_name)
RETURN
END
SELECT * FROMcreate_new_team('Team1');;
Ergebnis¶
TYPE |
NAME |
|---|---|
SMALL_TEAM |
TEAM1 |
Warnung
Diese Transformation wird angewendet, wenn nur ein Wert eingefügt werden soll. Bei mehr als einem Wert müssen Sie eine gespeicherte Prozedur verwenden.
Komplexe Fälle¶
Das Beispiel ist ein komplexer Fall, der verschachtelte if-Anweisungen verwendet und einen Wert abhängig von der Bedingung „true“ einfügt.
Transact-SQL¶
MULTI-STATEMENT TABLE-VALUED¶
CREATE OR ALTER FUNCTION vacation_status(@id VARCHAR (50))
RETURNS @status TABLE (vacation_status VARCHAR(30))
AS
BEGIN
DECLARE @hire_date DATETIME
SET @hire_date = (SELECT @hire_date FROM employee WHERE employeeId = @id)
DECLARE @vacation_hours INT
SET @vacation_hours = (SELECT count(vacation_hours) FROM employee WHERE employeeId = @id)
DECLARE @time_working INT
SET @time_working = (SELECT DATEDIFF(MONTH, @hire_date,GETDATE()))
IF (@vacation_hours > 0)
BEGIN
IF (@time_working > 3)
BEGIN
IF (@vacation_hours < 120)
BEGIN
INSERT INTO @status VALUES ('Ok')
END
IF (@vacation_hours = 120)
BEGIN
INSERT INTO @status values ('In the limit')
END
IF (@vacation_hours > 120)
BEGIN
INSERT INTO @status VALUES ('With excess')
END
END
ELSE
BEGIN
INSERT INTO @status values ('Hired recently')
END
END
ELSE
BEGIN
INSERT INTO @status values ('No hours')
END
RETURN
END
SELECT * FROM vacation_status('adventure-worksken0')
Ergebnis¶
VACATION_STATUS |
|---|
OK |
Snowflake SQL¶
MULTI-STATEMENT TABLE-VALUED¶
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'TABLE VALUED FUNCTIONS' NODE ***/!!!
CREATE OR ALTER FUNCTION vacation_status (ID STRING)
RETURNS STATUS TABLE (
vacation_status VARCHAR(30))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
BEGIN
DECLARE @hire_date DATETIME
SET @hire_date = (SELECT @hire_date FROM employee WHERE employeeId = @id)
DECLARE @vacation_hours INT
SET @vacation_hours = (SELECT count(vacation_hours) FROM employee WHERE employeeId = @id)
DECLARE @time_working INT
SET @time_working = (SELECT DATEDIFF(MONTH, @hire_date,GETDATE()))
IF (@vacation_hours > 0)
BEGIN
IF (@time_working > 3)
BEGIN
IF (@vacation_hours < 120)
BEGIN
INSERT INTO @status VALUES ('Ok')
END
IF (@vacation_hours = 120)
BEGIN
INSERT INTO @status values ('In the limit')
END
IF (@vacation_hours > 120)
BEGIN
INSERT INTO @status VALUES ('With excess')
END
END
ELSE
BEGIN
INSERT INTO @status values ('Hired recently')
END
END
ELSE
BEGIN
INSERT INTO @status values ('No hours')
END
RETURN
END
SELECT * FROM vacation_status('adventure-worksken0');
Zweiter Tab¶
VACATION_STATUS |
|---|
OK |
Bekannte Probleme¶
WHILE-Anweisungen in Verbindung mit Abfragen¶
Das Problem bei diesem Beispiel ist, dass es keine Möglichkeit gibt, die WHILE-Anweisung innerhalb der WITH-Klausel des Haupt-Select in eine CTE umzuwandeln. Dadurch sind wir gezwungen, diese Anweisung in eine gespeicherte Prozedur umzuwandeln, um die gleiche Logik zu erhalten.
Transact-SQL¶
MULTI-STATEMENT TABLE-VALUED¶
--Additional Params: -t JavaScript
CREATE OR ALTER FUNCTION get_group_name
(@department_id INT)
RETURNS @group_names TABLE (group_name VARCHAR(15))
AS
BEGIN
DECLARE @name VARCHAR(30) = 'Another Department'
WHILE @name = 'Another Department'
BEGIN
IF (@department_id < 3)
BEGIN
SET @name = 'engineering'
END
IF @department_id = 3
BEGIN
SET @name = 'Tool Design'
END
SELECT @department_id = @department_id / 3
END
INSERT @group_names SELECT @name
RETURN
END
SELECT * FROM get_group_name(9);
Ergebnis¶
GROUP_NAME |
|---|
Tool Design |
Snowflake SQL¶
MULTI-STATEMENT TABLE-VALUED¶
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'TABLE VALUED FUNCTIONS' NODE ***/!!!
CREATE OR ALTER FUNCTION get_group_name
(DEPARTMENT_ID INT)
RETURNS @group_names TABLE (
group_name VARCHAR(15))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
BEGIN
DECLARE @name VARCHAR(30) = 'Another Department'
WHILE @name = 'Another Department'
BEGIN
IF (@department_id < 3)
BEGIN
SET @name = 'engineering'
END
IF @department_id = 3
BEGIN
SET @name = 'Tool Design'
END
SELECT @department_id = @department_id / 3
END
INSERT @group_names SELECT @name
RETURN
END
SELECT * FROM get_group_name(9);;
Ergebnis¶
GROUP_NAME |
|---|
Tool Design |
Cursor deklarieren¶
Benutzerdefinierte Funktionen können DECLARE, OPEN, FETCH, CLOSE oder DEALLOCATE für einen CURSOR nicht verwenden. Verwenden Sie eine gespeicherte Prozedur, um mit Cursors zu arbeiten.
Transact-SQL¶
MULTI-STATEMENT TABLE-VALUED¶
--Additional Params: -t JavaScript
CREATE OR ALTER FUNCTION amount_new_specimens(@id int)
RETURNS @new_specimens TABLE (amount int)
AS
BEGIN
DECLARE @first_specimen VARCHAR(30) ;
set @first_specimen = (select name_specimen from specimen where specimen_id = @id);
DECLARE @second_specimen VARCHAR(30);
DECLARE @specimens TABLE (name_specimen VARCHAR(30))
DECLARE Cursor1 CURSOR
FOR SELECT name_specimen
FROM specimen
OPEN cursor1
FETCH NEXT FROM cursor1
INTO @second_specimen;
WHILE @@FETCH_STATUS = 0
BEGIN
IF @first_specimen <> @second_specimen
BEGIN
INSERT INTO @specimens values (CONCAT_WS('-', @first_specimen, @second_specimen))
END
FETCH NEXT FROM cursor1
INTO @second_specimen;
END
CLOSE cursor1;
DEALLOCATE cursor1;
INSERT INTO @new_specimens SELECT COUNT(*) FROM @specimens
RETURN
END
SELECT * FROM amount_new_specimens(1);
Ergebnis¶
AMOUNT |
|---|
3 |
Snowflake SQL¶
MULTI-STATEMENT TABLE-VALUED¶
--Additional Params: -t JavaScript
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'TABLE VALUED FUNCTIONS' NODE ***/!!!
CREATE OR ALTER FUNCTION amount_new_specimens (ID INT)
RETURNS @new_specimens TABLE (
amount INT
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
BEGIN
DECLARE @first_specimen VARCHAR(30) ;
set @first_specimen = (select name_specimen from specimen where specimen_id = @id);
DECLARE @second_specimen VARCHAR(30);
DECLARE @specimens TABLE (name_specimen VARCHAR(30))
DECLARE Cursor1 CURSOR
FOR SELECT name_specimen
FROM specimen
OPEN cursor1
FETCH NEXT FROM cursor1
INTO @second_specimen;
WHILE @@FETCH_STATUS = 0
BEGIN
IF @first_specimen <> @second_specimen
BEGIN
INSERT INTO @specimens values (CONCAT_WS('-', @first_specimen, @second_specimen))
END
FETCH NEXT FROM cursor1
INTO @second_specimen;
END
CLOSE cursor1;
DEALLOCATE cursor1;
INSERT INTO @new_specimens SELECT COUNT(*) FROM @specimens
RETURN
END
SELECT * FROM amount_new_specimens(1);;
Ergebnis¶
AMOUNT |
|---|
3 |
Verschiedene Anweisungen werden in allgemeinen Tabellenausdrücken nicht unterstützt¶
Die Klauseln UPDATE, INSERT, DELETE, ALTER oder DROP werden im Body von allgemeinen Tabellenausdrücken nicht unterstützt, auch nicht nach ihrer Deklaration mit einem Delimitator. Aus diesem Grund kann die Funktion so geändert werden, dass sie als gespeicherte Prozedur funktioniert.
Transact-SQL¶
MULTI-STATEMENT TABLE-VALUED¶
--Additional Params: -t JavaScript
CREATE OR ALTER PROCEDURE product_history
AS
BEGIN
DECLARE @product_history TABLE (
product_name NVARCHAR(50),
rating INT
)
INSERT INTO @product_history
SELECT P.Name AS product_name, AVG(ALL R.rating) FROM Production.product P
INNER JOIN Production.product_review R
ON R.product_ID = P.product_ID
GROUP BY P.Name;
DELETE FROM @product_history
WHERE rating < 2;
SELECT * FROM @product_history;
END
GO;
EXEC product_history
Ergebnis¶
PRODUCT_NAME |
Bewertung |
|---|---|
HL Mountain Pedal |
3 |
Mountain Bike Socks, M |
5 |
Road-550-W Yellow, 40 |
5 |
Snowflake SQL¶
MULTI-STATEMENT TABLE-VALUED¶
CREATE OR REPLACE PROCEDURE product_history ()
RETURNS STRING
LANGUAGE JAVASCRIPT
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
EXECUTE AS CALLER
AS
$$
// REGION SnowConvert AI Helpers Code
var _RS, ROW_COUNT, _ROWS, MESSAGE_TEXT, SQLCODE = 0, SQLSTATE = '00000', OBJECT_SCHEMA_NAME = 'UNKNOWN', ERROR_HANDLERS, NUM_ROWS_AFFECTED, PROC_NAME = arguments.callee.name, DOLLAR_DOLLAR = '$' + '$';
function* sqlsplit(sql) {
var part = '';
var ismark = () => sql[i] == '$' && sql[i + 1] == '$';
for(var i = 0;i < sql.length;i++) {
if (sql[i] == ';') {
yield part + sql[i];
part = '';
} else if (ismark()) {
part += sql[i++] + sql[i++];
while ( i < sql.length && !ismark() ) {
part += sql[i++];
}
part += sql[i] + sql[i++];
} else part += sql[i];
}
if (part.trim().length) yield part;
};
var formatDate = (arg) => (new Date(arg - (arg.getTimezoneOffset() * 60000))).toISOString().slice(0,-1);
var fixBind = function (arg) {
arg = arg == undefined ? null : arg instanceof Date ? formatDate(arg) : arg;
return arg;
};
var EXEC = (stmt,binds = [],severity = "16",noCatch = false) => {
binds = binds ? binds.map(fixBind) : binds;
for(var stmt of sqlsplit(stmt)) {
try {
_RS = snowflake.createStatement({
sqlText : stmt,
binds : binds
});
_ROWS = _RS.execute();
ROW_COUNT = _RS.getRowCount();
NUM_ROWS_AFFECTED = _RS.getNumRowsAffected();
return {
THEN : (action) => !SQLCODE && action(fetch(_ROWS))
};
} catch(error) {
let rStack = new RegExp('At .*, line (\\d+) position (\\d+)');
let stackLine = error.stackTraceTxt.match(rStack) || [0,-1];
MESSAGE_TEXT = error.message.toString();
SQLCODE = error.code.toString();
SQLSTATE = error.state.toString();
snowflake.execute({
sqlText : `SELECT UPDATE_ERROR_VARS_UDF(?,?,?,?,?,?)`,
binds : [stackLine[1],SQLCODE,SQLSTATE,MESSAGE_TEXT,PROC_NAME,severity]
});
throw error;
}
}
};
// END REGION
EXEC(`CREATE OR REPLACE TEMPORARY TABLE T_product_history (
product_name VARCHAR(50),
rating INT
)`);
EXEC(` INSERT INTO T_product_history
SELECT
P.Name AS product_name,
AVG(ALL R.rating) FROM
Production.product P
INNER JOIN
Production.product_review R
ON R.product_ID = P.product_ID
GROUP BY
P.Name`);
EXEC(`DELETE FROM
T_product_history
WHERE
rating < 2`);
EXEC(`
SELECT
*
FROM
T_product_history`);
$$;
;
CALL product_history();
Ergebnis¶
PRODUCT_NAME |
Bewertung |
|---|---|
HL Mountain Pedal |
3 |
Mountain Bike Socks, M |
5 |
Road-550-W Yellow, 40 |
5 |
Zugehörige EWIs¶
SSC-EWI-0040: Anweisung nicht unterstützt.#x20;
[SSC-EWI-0073](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0073): Überprüfung der Funktionsäquivalenz ausstehend
SCALAR¶
Übersetzungsreferenz zur Konvertierung von Transact-SQL UDF (benutzerdefinierten Funktionen) mit dem „scalar“-Rückgabetyp an Snowflake.
Applies to
SQL Server
Azure Synapse Analytics
Beschreibung¶
Bemerkung
Einige Teile des Ausgabecodes wurden aus Gründen der Übersichtlichkeit weggelassen.
Eine benutzerdefinierte Skalarfunktion ist eine Transact-SQL- oder Common Language Runtime(CLR)-Routine, die Parameter akzeptiert, eine Aktion ausführt, z. B. eine komplexe Berechnung, und das Ergebnis dieser Aktion als Skalarwert zurückgibt. (SQL Server-Sprachreferenz – Unterabschnitt ReferenceCREATE FUNCTION).
Bemerkung
Diese Funktionen werden in der Regel innerhalb der Anweisung SELECToder bei der Einrichtung einer einzelnen Variablen (höchstwahrscheinlich innerhalb einer gespeicherten Prozedur) verwendet.
Transact-SQL-Syntax¶
-- Transact-SQL Scalar Function Syntax
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name
( [ { @parameter_name [ AS ][ type_schema_name. ] parameter_data_type
[ = default ] [ READONLY ] }
[ ,...n ]
]
)
RETURNS return_data_type
[ WITH <function_option> [ ,...n ] ]
[ AS ]
BEGIN
function_body
RETURN scalar_expression
END
[ ; ]
Snowflake-Syntax¶
Snowflake erlaubt 3 verschiedene Sprachen in den benutzerdefinierten Funktionen:
SQL
JavaScript
Java
Vorerst unterstützt SnowConvert AI nur SQL und JavaScript als Zielsprachen.
SQL¶
Bemerkung
Benutzerdefinierte SQL-Funktionen unterstützen nur eine Abfrage als Body. Sie können aus der Datenbank lesen, aber nicht schreiben oder verändern. (Referenz zu skalaren SQL UDFs).
CREATE [ OR REPLACE ] [ SECURE ] FUNCTION <name> ( [ <arg_name> <arg_data_type> ] [ , ... ] )
RETURNS { <result_data_type> | TABLE ( <col_name> <col_data_type> [ , ... ] ) }
[ [ NOT ] NULL ]
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ VOLATILE | IMMUTABLE ]
[ COMMENT = '<string_literal>' ]
AS '<function_definition>'
JavaScript¶
Bemerkung
Benutzerdefinierte JavaScript-Funktionen erlauben mehrere Anweisungen in ihren Bodys, können aber keine Abfragen an die Datenbank durchführen. (Referenz zu skalaren JavaScript UDFs)
CREATE [ OR REPLACE ] [ SECURE ] FUNCTION <name> ( [ <arg_name> <arg_data_type> ] [ , ... ] )
RETURNS { <result_data_type> | TABLE ( <col_name> <col_data_type> [ , ... ] ) }
[ [ NOT ] NULL ]
LANGUAGE JAVASCRIPT
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ VOLATILE | IMMUTABLE ]
[ COMMENT = '<string_literal>' ]
AS '<function_definition>'
Beispielhafte Quellcode-Muster¶
SET- und DECLARE-Anweisungen¶
Die häufigsten Anweisungen in Funktions-Bodys sind die Anweisungen DECLARE und SET. Bei DECLARE-Anweisungen ohne Standardwert wird die Transformation ignoriert. SET-Anweisungen und DECLARE-Anweisungen mit einem Standardwert werden in COMMON TABLE EXPRESSION umgewandelt. Jeder gemeinsame Tabellenausdruck enthält eine Spalte, die den Wert der lokalen Variablen darstellt.
Transact-SQL¶
Abfrage¶
CREATE OR ALTER FUNCTION PURCHASING.GetVendorName()
RETURNS NVARCHAR(50) AS
BEGIN
DECLARE @result NVARCHAR(50)
DECLARE @BUSINESSENTITYID INT
SET @BUSINESSENTITYID = 1492
SELECT @result = Name FROM PURCHASING.VENDOR WHERE BUSINESSENTITYID = @BUSINESSENTITYID
RETURN @result
END
GO
SELECT PURCHASING.GetVendorName() as vendor_name;
Ergebnis¶
vendor_name |
|---|
Australia Bike Retailer |
Snowflake¶
Abfrage¶
CREATE OR REPLACE FUNCTION PURCHASING.GetVendorName ()
RETURNS VARCHAR(50)
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
$$
WITH CTE1 AS
(
SELECT
1492 AS BUSINESSENTITYID
),
CTE2 AS
(
SELECT
Name AS RESULT
FROM
PURCHASING.VENDOR
WHERE
BUSINESSENTITYID = (
SELECT
BUSINESSENTITYID
FROM
CTE1
)
)
SELECT
RESULT
FROM
CTE2
$$;
SELECT
PURCHASING.GetVendorName() as vendor_name;
Ergebnis¶
VENDOR_NAME |
|---|
Australia Bike Retailer |
Transformation von IF/ELSE-Anweisung¶
IF/ELSE-Anweisungen können auf unterschiedliche Weise gehandhabt werden. Sie können entweder in Javascript oder in SQL transformiert werden, indem die CASE EXPRESSION innerhalb der SELECT-Anweisung die Bedingungen innerhalb der Abfragen zulässt. Während die Transformation in Javascript ziemlich einfach ist, ist die CASE-Anweisung auf den ersten Blick vielleicht nicht so offensichtlich.
Transact-SQL¶
Abfrage¶
CREATE OR ALTER FUNCTION PURCHASING.HasActiveFlag(@BusinessEntityID int)
RETURNS VARCHAR(10) AS
BEGIN
DECLARE @result VARCHAR(10)
DECLARE @ActiveFlag BIT
SELECT @ActiveFlag = ActiveFlag from PURCHASING.VENDOR v where v.BUSINESSENTITYID = @BusinessEntityID
IF @ActiveFlag = 1
SET @result = 'YES'
ELSE IF @ActiveFlag = 0
SET @result = 'NO'
RETURN @result
END
GO
SELECT PURCHASING.HasActiveFlag(1516) as has_active_flag;
Ergebnis¶
has_active_flag |
|---|
NO |
Snowflake¶
Abfrage¶
CREATE OR REPLACE FUNCTION PURCHASING.HasActiveFlag (P_BUSINESSENTITYID INT)
RETURNS VARCHAR(10)
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
$$
WITH CTE1 AS
(
SELECT
ActiveFlag AS ACTIVEFLAG
from
PURCHASING.VENDOR v
where
v.BUSINESSENTITYID = P_BUSINESSENTITYID
),
CTE2 AS
(
SELECT
CASE
WHEN (
SELECT
ACTIVEFLAG
FROM
CTE1
) = 1
THEN 'YES'
WHEN (
SELECT
ACTIVEFLAG
FROM
CTE1
) = 0
THEN 'NO'
END AS RESULT
)
SELECT
RESULT
FROM
CTE2
$$;
SELECT
PURCHASING.HasActiveFlag(1516) as has_active_flag;
Ergebnis¶
HAS_ACTIVE_FLAG |
|---|
NO |
NESTED-Anweisungen¶
Bei NESTED-Anweisungen wird die strukturierte Programmierung in eine einzige Abfrage umgewandelt. Die Anweisungen in der Ablaufsteuerung werden in Tabellenstrukturen verschachtelt, um die Ausführungsreihenfolge beizubehalten.
Bemerkung
CASE EXPRESSIONS kann nur einen Wert pro Anweisung zurückgeben
Beispiel¶
Bemerkung
Der folgende Code ist in beiden Programmierparadigmen funktional gleichwertig.
Strukturierte Programmierung¶
DECLARE @VendorId AS int;
DECLARE @AccountNumber AS VARCHAR(50);
SELECT @VendorId = poh.VendorID
FROM Purchasing.PurchaseOrderHeader poh
WHERE PurchaseOrderID = 1
SELECT @AccountNumber = v.AccountNumber
FROM Purchasing.Vendor v
WHERE v.BusinessEntityID = @VendorId
SQL¶
SELECT V.AccountNumber AccountNumber
FROM (SELECT poh.VendorID VendorId
FROM Purchasing.PurchaseOrderHeader poh
WHERE PurchaseOrderID = 1
) T1, Purchasing.Vendor v
WHERE v.BusinessEntityID = T1.VendorId
Ergebnis¶
AccountNumber |
|---|
LITWARE0001 |
Bedingte Variablen durch SELECTs¶
Die Definition und Zuweisung von Variablen innerhalb von bedingten Anweisungen ist tendenziell etwas problematisch, da Verweise auf die Variable weiter unten im Code wissen müssten, wo die Variable zuletzt geändert wurde. Und nicht nur das: Wenn der Verweis innerhalb einer anderen bedingten Anweisung steht, müsste es eine Art Umleitung geben, die auf die vorherige bekannte Zuweisung an die Variable verweist.
Verschärft wird dies alles noch durch Verschachtelungen und komplexe Abfragen im Eingabecode. Aus diesem Grund wird ein bestimmter EWI hinzugefügt, wenn diese Muster gefunden werden.
Im folgenden Szenario kann die erste IF-Anweisung ohne Probleme umgewandelt werden, da der Inhalt einfach genug ist. Die zweite und dritte IF-Anweisung sind auskommentiert, weil sie derzeit nicht unterstützt werden, da es andere Anweisungen als Variablenzuweisungen durch SELECT gibt.
SQL Server¶
Abfrage¶
CREATE or ALTER FUNCTION PURCHASING.SELECTINUDF (
@param1 varchar(12)
)
RETURNS int
AS
BEGIN
declare @var1 int;
declare @var2 int;
declare @var3 int;
IF @param1 = 'first'
BEGIN
select @var1 = col1 + 10 from table1 WHERE id = 0;
select @var2 = col1 + 20 from table1 WHERE id = 0;
select @var3 = col1 + 30 from table1 WHERE id = 0;
END
IF @param1 = 'second'
BEGIN
declare @var4 int = 10;
select @var1 = col1 + 40 from table1 WHERE id = 0;
select @var2 = col1 + 40 from table1 WHERE id = 0;
END
IF @param1 = 'third'
BEGIN
select col1 from table1 where id = 0;
select @var1 = col1 + 50 from table1 WHERE id = 0;
select @var2 = col1 + 50 from table1 WHERE id = 0;
END
RETURN @var1
END
SELECT PURCHASING.SELECTINUDF('first') as result; -- Assuming table1.col1 is 0 when ID = 0
Ergebnis¶
RESULT |
|---|
10 |
Snowflake¶
Abfrage¶
CREATE OR REPLACE FUNCTION PURCHASING.SELECTINUDF (PARAM1 STRING)
RETURNS INT
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
$$
WITH CTE1 AS
(
SELECT
CASE
WHEN PARAM1 = 'first'
THEN (SELECT
col1 + 10 AS VAR1 from
table1
WHERE
id = 0)
END AS VAR1,
CASE
WHEN PARAM1 = 'first'
THEN (SELECT
col1 + 20 AS VAR2 from
table1
WHERE
id = 0)
END AS VAR2,
CASE
WHEN PARAM1 = 'first'
THEN (SELECT
col1 + 30 AS VAR3 from
table1
WHERE
id = 0)
END AS VAR3
),
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'IF STATEMENT' NODE ***/!!!
CTE2 AS
(
/* IF @param1 = 'second'
BEGIN
declare @var4 int = 10;
select @var1 = col1 + 40 from table1 WHERE id = 0;
select @var2 = col1 + 40 from table1 WHERE id = 0;
END*/
SELECT
null
),
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'IF STATEMENT' NODE ***/!!!
CTE3 AS
(
/* IF @param1 = 'third'
BEGIN
select col1 from table1 where id = 0;
select @var1 = col1 + 50 from table1 WHERE id = 0;
select @var2 = col1 + 50 from table1 WHERE id = 0;
END*/
SELECT
null
),
CTE4 AS
(
SELECT
PURCHASING.SELECTINUDF('first') as result
)
SELECT
VAR1
FROM
CTE4
$$ -- Assuming table1.col1 is 0 when ID = 0
;
Ergebnis¶
RESULT |
|---|
10 |
Eine Variable zuweisen und zurückgeben¶
In diesem einfachen Muster gibt es eine Variablendeklaration, dann wird diese Variable mit einer SELECT-Anweisung gesetzt und schließlich zurückgegeben. Diese wird in einen allgemeinen Tabellenausdruck umgewandelt, um die ursprüngliche Verhaltensweise beizubehalten.
SQL Server¶
Abfrage¶
CREATE OR ALTER FUNCTION Purchasing.GetTotalFreight()
RETURNS MONEY AS
BEGIN
DECLARE @Result MONEY
SELECT @Result = ISNULL(SUM(t.Freight), 0) from Purchasing.PurchaseOrderHeader t
return @Result
END
GO
select Purchasing.GetTotalFreight() as Result;
Ergebnis¶
Ergebnis |
|---|
1583978.2263 |
Snowflake¶
Abfrage¶
CREATE OR REPLACE FUNCTION Purchasing.GetTotalFreight ()
RETURNS NUMBER(38, 4)
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
$$
WITH CTE1 AS
(
SELECT
NVL(SUM(t.Freight), 0) AS RESULT from
Purchasing.PurchaseOrderHeader t
)
SELECT
RESULT
FROM
CTE1
$$;
select
Purchasing.GetTotalFreight() as Result;
Ergebnis¶
RESULT |
|---|
1583978.2263 |
Aufrufe mehrerer Funktionen¶
Für dieses spezielle Muster gibt es keine offensichtlichen Abfragen, aber es gibt mehrere Aufrufe mehrerer Funktionen, die mit derselben Variable arbeiten und sie am Ende zurückgeben. Da Snowflake nur Abfragen innerhalb seiner Funktionen unterstützt, besteht die Lösung für diesen Block darin, ihn zu einem Select hinzuzufügen und die Aufrufe darin zu verschachteln, wobei sicherzustellen ist, dass der Rückgabewert mit dem der Quelle übereinstimmt.
SQL Server¶
Abfrage¶
CREATE OR ALTER FUNCTION PURCHASING.Foo
(
@PARAM1 INT
)
RETURNS varchar(25)
AS
BEGIN
DECLARE @filter INT = @PARAM1
DECLARE @NAME VARCHAR(25) = (SELECT Name from Purchasing.Vendor v where BusinessEntityID = @filter)
SET @NAME = REPLACE(@NAME, 'Australia', 'USA')
SET @NAME = REPLACE(@NAME, 'Bike', 'Car')
RETURN @NAME
END
GO
SELECT PURCHASING.Foo(1492) AS Name;
Ergebnis¶
Name |
|---|
USA Car Retailer |
Snowflake¶
Abfrage¶
CREATE OR REPLACE FUNCTION PURCHASING.Foo (PARAM1 INT)
RETURNS VARCHAR(25)
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
$$
WITH CTE1 AS
(
SELECT
PARAM1 AS FILTER
),
CTE2 AS
(
SELECT
(SELECT
Name
from
Purchasing.Vendor v
where
BusinessEntityID = (
SELECT
FILTER
FROM
CTE1
)
) AS NAME
),
CTE3 AS
(
SELECT
REPLACE((
SELECT
NAME
FROM
CTE3
), 'Australia', 'USA') AS NAME
),
CTE4 AS
(
SELECT
REPLACE((
SELECT
NAME
FROM
CTE4
), 'Bike', 'Car') AS NAME
)
SELECT
NAME
FROM
CTE4
$$;
SELECT
PURCHASING.Foo(1492) AS Name;
Ergebnis¶
NAME |
|---|
USA Car Retailer |
Eine Variable basierend auf mehreren IF Bedingungen erhöhen und ihren Wert zurückgeben¶
Bei diesem Muster wird eine Variable durch mehrere IF-Bedingungen verändert (in diesem Fall erhöht). Zu Beginn wird ein Satz von Variablen initialisiert und verwendet, um zu bestimmen, ob die Ergebnisvariable erhöht werden soll oder nicht. Schließlich wird die Ergebnisvariable zurückgegeben.
SQL Server¶
Abfrage¶
CREATE OR ALTER FUNCTION PURCHASING.FOO()
RETURNS MONEY
AS
BEGIN
declare @firstValue MONEY
declare @secondValue MONEY
declare @Result MONEY
select @Result = 0
select @firstValue = SubTotal from Purchasing.PurchaseOrderHeader where PurchaseOrderID = 1
select @secondValue = SubTotal from Purchasing.PurchaseOrderHeader where PurchaseOrderID = 2
if @firstValue is not null
select @Result = @Result + @firstValue
if @secondValue is not null
select @Result = @Result + @secondValue
return @Result
END
GO
SELECT PURCHASING.Foo() AS Result;
Ergebnis¶
Ergebnis |
|---|
473.1415 |
Snowflake¶
Abfrage¶
CREATE OR REPLACE FUNCTION PURCHASING.FOO ()
RETURNS NUMBER(38, 4)
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
$$
WITH CTE1 AS
(
select
0 AS RESULT
),
CTE2 AS
(
select
SubTotal AS FIRSTVALUE
from
Purchasing.PurchaseOrderHeader
where
PurchaseOrderID = 1
),
CTE3 AS
(
select
SubTotal AS SECONDVALUE
from
Purchasing.PurchaseOrderHeader
where
PurchaseOrderID = 2
),
CTE4 AS
(
SELECT
CASE
WHEN (
SELECT
FIRSTVALUE
FROM
CTE2
) is not null
THEN (
select
(
SELECT
RESULT
FROM
CTE1
) + (
SELECT
FIRSTVALUE
FROM
CTE2
) AS RESULT)
END AS RESULT
),
CTE5 AS
(
SELECT
CASE
WHEN (
SELECT
SECONDVALUE
FROM
CTE3
) is not null
THEN (
select
(
SELECT
RESULT
FROM
CTE1
) + (
SELECT
SECONDVALUE
FROM
CTE3
) AS RESULT)
ELSE (SELECT
RESULT
FROM
CTE4)
END AS RESULT
)
SELECT
RESULT
FROM
CTE5
$$;
SELECT
PURCHASING.Foo() AS Result;
Ergebnis¶
RESULT |
|---|
473.1415 |
Zwei oder mehrere RETURN-Anweisungen¶
Bei diesem Muster wird der IF-Block, der die RETURN-Klausel enthält, die den Codefluss unterbricht, am Ende des Bodys hinzugefügt, wie die letzte auszuführende Anweisung in einem CASE-Ausdruck.
Grundlegender Fall¶
In diesem speziellen Szenario gibt es keine Logik zwischen der bedingten RETURN-Anweisung und der abschließenden RETURN-Anweisung, so dass der gesamte Text-Bodys einem einzigen CASE EXPRESSION zugeordnet wird.
SQL Server¶
Abfrage¶
CREATE OR ALTER FUNCTION [PURCHASING].[FOO] ()
RETURNS INT
AS
BEGIN
IF exists (SELECT PreferredVendorStatus FROM Purchasing.Vendor v )
RETURN 1
RETURN 0
END
GO
SELECT PURCHASING.FOO() as result;
Ergebnis¶
result |
|---|
1 |
Snowflake¶
Abfrage¶
CREATE OR REPLACE FUNCTION PURCHASING.FOO ()
RETURNS INT
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
$$
SELECT
CASE
WHEN exists (SELECT
PreferredVendorStatus
FROM
Purchasing.Vendor v
)
THEN 1
ELSE 0
END
$$;
SELECT
PURCHASING.FOO() as result;
Ergebnis¶
RESULT |
|---|
1 |
Allgemeine Tabellenausdrücke¶
Allgemeine Tabellenausdrücke bleiben im ursprünglichen Code erhalten und werden mit den generierten verkettet. SnowConvert AI kann zuerst alle ursprünglichen COMMON TABLE EXPRESSION-Namen identifizieren, um die Generierunmg doppelter Namen zu vermeiden.
SQL Server¶
Abfrage¶
CREATE OR ALTER FUNCTION [PURCHASING].[FOO]
(
@status INT
)
Returns INT
As
Begin
Declare @result as int = 0
;WITH ctetable(RevisionNumber) as
(
SELECT RevisionNumber
FROM Purchasing.PurchaseOrderHeader poh
where poh.Status = @status
),
finalCte As
(
SELECT RevisionNumber FROM ctetable
)
Select @result = count(RevisionNumber) from finalCte
return @result;
End
GO
SELECT PURCHASING.FOO(4) as result;
Ergebnis¶
result |
|---|
3689 |
Snowflake¶
Abfrage¶
CREATE OR REPLACE FUNCTION PURCHASING.FOO (STATUS INT)
Returns INT
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},"attributes":{"component":"transact"}}'
AS
$$
WITH CTE1 AS
(
SELECT
0 AS RESULT
),
ctetable (
RevisionNumber
) as
(
SELECT
RevisionNumber
FROM
Purchasing.PurchaseOrderHeader poh
where
poh.Status = STATUS
),
finalCte As
(
SELECT
RevisionNumber
FROM
ctetable
),
CTE2 AS
(
Select
COUNT(RevisionNumber) AS RESULT from
finalCte
)
SELECT
RESULT
FROM
CTE2
$$;
SELECT
PURCHASING.FOO(4) as result;
Ergebnis¶
RESULT |
|---|
3689 |
In JavaScript UDFs umwandeln¶
Wenn es mehrere Anweisungen gibt und die Funktion in keiner Weise auf die Datenbank zugreift, kann sie unter Beibehaltung der Funktionsäquivalenz in eine JavaScript-Funktion umgewandelt werden
SQL Server¶
Abfrage 1¶
CREATE OR ALTER FUNCTION PURCHASING.GetFiscalYear
(
@DATE AS DATETIME
)
RETURNS INT
AS
BEGIN
DECLARE @FiscalYear AS INT
DECLARE @CurMonth AS INT
SET @CurMonth = DATEPART(M,@DATE)
SET @FiscalYear = DATEPART(YYYY, @DATE)
IF (@CurMonth >= 7)
BEGIN
SET @FiscalYear = @FiscalYear + 1
END
RETURN @FiscalYear
END
GO
SELECT PURCHASING.GetFiscalYear('2020-10-10') as DATE;
Abfrage 2¶
CREATE OR ALTER FUNCTION PURCHASING.[getCleanChargeCode]
(
@ChargeCode varchar(50)
)
returns varchar(50) as
begin
declare @CleanChargeCode varchar(50),@Len int,@Pos int=2
set @Pos=LEN(@ChargeCode)-1
while @Pos > 1
begin
set @CleanChargeCode=RIGHT(@ChargeCode,@Pos)
if TRY_CAST(@CleanChargeCode as bigint) is not null
return @CleanChargeCode
set @Pos=@Pos-1
end
set @Pos=LEN(@ChargeCode)-1
while @Pos > 1
begin
set @CleanChargeCode=LEFT(@ChargeCode,@Pos)
if TRY_CAST(@CleanChargeCode as bigint) is not null
return @CleanChargeCode
set @Pos=@Pos-1
end
return null
end
GO
SELECT PURCHASING.[getCleanChargeCode]('16test') AS CleanChargeCode;
Ergebnis 1¶
DATE |
|---|
2021 |
Ergebnis 2¶
CleanChargeCode |
|---|
16 |
Snowflake¶
Abfrage 1¶
!!!RESOLVE EWI!!! /*** SSC-EWI-0068 - USER DEFINED FUNCTION WAS TRANSFORMED TO SNOWFLAKE PROCEDURE ***/!!!
CREATE OR REPLACE PROCEDURE PURCHASING.GetFiscalYear (DATE TIMESTAMP_NTZ(3))
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "07/11/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
FISCALYEAR INT;
CURMONTH INT;
BEGIN
CURMONTH := DATE_PART(month, :DATE :: TIMESTAMP);
FISCALYEAR := DATE_PART(year, :DATE :: TIMESTAMP);
IF ((:CURMONTH >= 7)) THEN
BEGIN
FISCALYEAR := :FISCALYEAR + 1;
END;
END IF;
RETURN :FISCALYEAR;
END;
$$;
SELECT
PURCHASING.GetFiscalYear('2020-10-10') !!!RESOLVE EWI!!! /*** SSC-EWI-0067 - UDF WAS TRANSFORMED TO SNOWFLAKE PROCEDURE, CALLING PROCEDURES INSIDE QUERIES IS NOT SUPPORTED ***/!!! as DATE;
Abfrage 2¶
!!!RESOLVE EWI!!! /*** SSC-EWI-0068 - USER DEFINED FUNCTION WAS TRANSFORMED TO SNOWFLAKE PROCEDURE ***/!!!
CREATE OR REPLACE PROCEDURE PURCHASING.getCleanChargeCode (CHARGECODE STRING)
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "07/16/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
CLEANCHARGECODE VARCHAR(50);
LEN INT;
POS INT := 2;
BEGIN
POS := LEN(:CHARGECODE)-1;
WHILE (:POS > 1) LOOP
CLEANCHARGECODE := RIGHT(:CHARGECODE, :POS);
IF (CAST(:CLEANCHARGECODE AS BIGINT) /*** SSC-FDM-TS0005 - TRY_CONVERT/TRY_CAST COULD NOT BE CONVERTED TO TRY_CAST ***/!!!RESOLVE EWI!!! /*** SSC-EWI-TS0074 - CAST RESULT MAY BE DIFFERENT FROM TRY_CAST FUNCTION DUE TO MISSING DEPENDENCIES ***/!!! is not null) THEN
RETURN :CLEANCHARGECODE;
END IF;
POS := :POS -1;
END LOOP;
POS := LEN(:CHARGECODE)-1;
WHILE (:POS > 1) LOOP
CLEANCHARGECODE := LEFT(:CHARGECODE, :POS);
IF (CAST(:CLEANCHARGECODE AS BIGINT) /*** SSC-FDM-TS0005 - TRY_CONVERT/TRY_CAST COULD NOT BE CONVERTED TO TRY_CAST ***/!!!RESOLVE EWI!!! /*** SSC-EWI-TS0074 - CAST RESULT MAY BE DIFFERENT FROM TRY_CAST FUNCTION DUE TO MISSING DEPENDENCIES ***/!!! is not null) THEN
RETURN :CLEANCHARGECODE;
END IF;
POS := :POS -1;
END LOOP;
RETURN null;
END;
$$;
SELECT
PURCHASING.getCleanChargeCode('16test') !!!RESOLVE EWI!!! /*** SSC-EWI-0067 - UDF WAS TRANSFORMED TO SNOWFLAKE PROCEDURE, CALLING PROCEDURES INSIDE QUERIES IS NOT SUPPORTED ***/!!! AS CleanChargeCode;
Ergebnis 1¶
DATE |
|---|
2021.0 |
Ergebnis 2¶
CLEANCHARGECODE |
|---|
16 |
Bekannte Probleme¶
Warnung
Benutzerdefinierte Funktionen können nicht verwendet werden, um Aktionen durchzuführen, die den Zustand der Datenbank verändern
Warnung
Benutzerdefinierte Funktionen können keine OUTPUT INTO- Klausel enthalten, die eine Tabelle als Ziel hat
Warnung
Benutzerdefinierte Funktionen können DECLARE, OPEN, FETCH, CLOSE oder DEALLOCATE für einen CURSOR nicht verwenden. Verwenden Sie eine gespeicherte Prozedur, wenn Sie Cursors verwenden müssen.
Warnung
Benutzerdefinierte Funktionen können keine CONTROL-OF-FLOW-Anweisungen wie WHILE ausführen, wenn es mindestens einen Aufruf an die Datenbank gibt
Warnung
Benutzerdefinierte Funktionen mit Referenzen auf andere benutzerdefinierte Funktionen, die in gespeicherte Prozeduren umgewandelt wurden, werden ebenfalls in Prozeduren umgewandelt.
Warnung
Benutzerdefinierte Funktionen, die @@ROWCOUNT verwenden, werden in SQL nicht unterstützt und sollten in gespeicherte Prozeduren umgewandelt werden, um die Funktionsäquivalenz zu wahren.
Warnung
Benutzerdefinierte Funktionen mit SELECT Anweisungen, die sich selbst eine Variable zuweisen, werden in Snowflake nicht unterstützt. Siehe auch SELECT @local_variable
Für alle nicht unterstützten Fälle prüfen Sie bitte die entsprechenden EWIs und die unten stehenden Muster, um Empfehlungen und mögliche Umgehungslösungen zu erhalten.
Andere Bedingungen als IF/ELSE-Anweisungen neben Abfragen¶
Das nächste Szenario beinhaltet die Verwendung der „WHILE-Anweisung“ zusammen mit anderen Abfragen. Das Problem bei diesem Beispiel ist, dass es keine Möglichkeit gibt, die WHILE-Anweisung innerhalb der WITH-Klausel des Haupt-Select in eine CTE umzuwandeln. Dadurch sind wir gezwungen, diese Anweisung in eine JavaScript-Prozedur umzuwandeln, um die gleiche Logik zu erhalten.
SQL Server¶
Abfrage¶
CREATE OR ALTER FUNCTION PURCHASING.FOO()
RETURNS INT
AS
BEGIN
DECLARE @i int = 0, @p int;
Select @p = COUNT(*) FROM PURCHASING.VENDOR
WHILE (@p < 1000)
BEGIN
SET @i = @i + 1
SET @p = @p + @i
END
IF (@i = 6)
RETURN 1
RETURN @p
END
GO
SELECT PURCHASING.FOO() as result;
Ergebnis¶
result |
|---|
1007 |
Snowflake
Abfrage¶
!!!RESOLVE EWI!!! /*** SSC-EWI-0068 - USER DEFINED FUNCTION WAS TRANSFORMED TO SNOWFLAKE PROCEDURE ***/!!!
CREATE OR REPLACE PROCEDURE PURCHASING.FOO ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "07/11/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
I INT := 0;
P INT;
BEGIN
Select
COUNT(*)
INTO
:P
FROM
PURCHASING.VENDOR;
WHILE (:P < 1000) LOOP
I := :I + 1;
P := :P + :I;
END LOOP;
IF ((:I = 6)) THEN
RETURN 1;
END IF;
RETURN :P;
END;
$$;
SELECT
PURCHASING.FOO() !!!RESOLVE EWI!!! /*** SSC-EWI-0067 - UDF WAS TRANSFORMED TO SNOWFLAKE PROCEDURE, CALLING PROCEDURES INSIDE QUERIES IS NOT SUPPORTED ***/!!! as result;
Ergebnis¶
FOO |
|---|
1007 |
Zuweisung einer Variablen unter Verwendung ihres eigenen Werts bei der Iteration durch einen Rowset¶
Im folgenden Beispiel wird die Variable @names verwendet, um mehrere Werte aus einer Spalte zu einer einzigen Zeichenfolge zu verketten. Die Variable wird wie gezeigt bei jeder Iteration aktualisiert, was von SnowFlake UDFs nicht unterstützt wird. Für dieses Szenario sollte die Funktion in eine Prozedur umgewandelt werden.
SQL Server
Abfrage¶
CREATE OR ALTER FUNCTION PURCHASING.FOO()
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE @names varchar(8000)
SET @names = ''
SELECT @names = ISNULL(@names + ' ', '') + Name from Purchasing.Vendor v
return @names
END
GO
select PURCHASING.FOO() as names;
Ergebnis¶
names |
|---|
Australia Bike Retailer Allenson Cycles Advanced Bicycles Trikes, Inc. Morgan Bike Accessories Cycling Master Chicago Rent-All Greenwood Athletic Company Compete Enterprises, Inc International Light Speed Training Systems Gardner Touring Cycles Internati |
Snowflake-Abfrage
!!!RESOLVE EWI!!! /*** SSC-EWI-0068 - USER DEFINED FUNCTION WAS TRANSFORMED TO SNOWFLAKE PROCEDURE ***/!!!
CREATE OR REPLACE PROCEDURE PURCHASING.FOO ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "07/11/2025", "domain": "no-domain-provided" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
NAMES VARCHAR(8000);
BEGIN
NAMES := '';
SELECT
NVL(:NAMES || ' ', '') + Name
INTO
:NAMES
from
Purchasing.Vendor v;
RETURN :NAMES;
END;
$$;
select
PURCHASING.FOO() !!!RESOLVE EWI!!! /*** SSC-EWI-0067 - UDF WAS TRANSFORMED TO SNOWFLAKE PROCEDURE, CALLING PROCEDURES INSIDE QUERIES IS NOT SUPPORTED ***/!!! as names;
Warnung
Beachten Sie bei den oben beschriebenen Szenarien die folgenden Beschränkungen:
Alle Aufrufe von benutzerdefinierten Funktionen in DML-Abfragen wie
SELECT,INSERT,DELETE,UPDATEoderMERGEwerden fehlschlagen, da Aufrufe von gespeicherten Prozeduren in diesen Abfragen nicht erlaubt sind.Aufrufen von benutzerdefinierten Funktionen innerhalb von Prozeduren sollte das Schlüsselwort
CALLvorangestellt werden.Benutzerdefinierte Funktionen, die in COMPUTED COLUMNS verwendet werden, schlagen bei der Ausführung fehl.
Zugehörige EWIs¶
[SSC-EWI-0067](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0067): UDF wurde in eine Snowflake-Prozedur umgewandelt, der Aufruf von Prozeduren innerhalb einer Abfrage wird nicht unterstützt.
SSC-EWI-0068: Die benutzerdefinierte Funktion wurde in eine Snowflake-Prozedur umgewandelt.
[SSC-EWI-0073](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0073): Überprüfung der Funktionsäquivalenz ausstehend.
UDF für Snowflake-Skript (SCALAR)¶
Übersetzungsreferenz für benutzerdefinierte SQL Server-Skalarfunktionen für Snowflake Scripting UDFs
Applies to
SQL Server
Azure Synapse Analytics
Beschreibung¶
SnowConvert unterstützt die Übersetzung von benutzerdefinierten SQL Server-Sklalarfunktionen direkt in Snowflake Scripting UDFs (SnowScript UDFs), wenn sie bestimmte Kriterien erfüllen, anstatt alle Funktionen in gespeicherte Prozeduren zu konvertieren.
Snowflake Scripting UDFs sind benutzerdefinierte Funktionen, die mit Snowflakes prozeduraler Sprachsyntax (SnowScript) innerhalb eines SQL UDF-Textkörpers geschrieben wurden. Sie unterstützen Variablen, Schleifen, bedingte Logik und die Ausnahmebehandlung.
Wenn Funktionen zu SnowScript UDFs werden¶
SnowConvert analysiert jeden SQL Server-Funktion und ermittelt automatisch das entsprechende Snowflake-Ziel. Eine Funktion wird zu einer SnowScript UDF, wenn sie nur prozedurale Logik ohne Datenzugriffsoperationen enthält.
Beispielhafte Quellcode-Muster¶
Einfache Berechnungsfunktion¶
Eine einfache Skalarfunktion, die Berechnungen durchführt, ohne Daten abzufragen.
SQL Server¶
CREATE FUNCTION dbo.CalculateProfit
(
@Cost DECIMAL(10,2),
@Revenue DECIMAL(10,2)
)
RETURNS DECIMAL(10,2)
AS
BEGIN
DECLARE @Profit DECIMAL(10,2)
SET @Profit = @Revenue - @Cost
RETURN @Profit
END
GO
SELECT dbo.CalculateProfit(100.00, 150.00) as Profit;
Ergebnis¶
Profit |
|---|
50,00 |
Snowflake (SnowScript UDF)¶
CREATE OR REPLACE FUNCTION dbo.CalculateProfit (COST DECIMAL(10,2), REVENUE DECIMAL(10,2))
RETURNS DECIMAL(10, 2)
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/09/2025", "domain": "no-domain-provided", "migrationid": "QsqZARsvG3aeleeXZB43fg==" }}'
AS
$$
DECLARE
PROFIT DECIMAL(10, 2);
BEGIN
PROFIT := :REVENUE - :COST;
RETURN :PROFIT;
END;
$$;
SELECT
dbo.CalculateProfit(100.00, 150.00) as Profit;
Ergebnis¶
PROFIT |
|---|
50,00 |
Funktion mit bedingter Logik (IF/ELSE)¶
Funktionen mit IF/ELSE-Anweisungen für Geschäftslogik.
SQL Server¶
CREATE FUNCTION dbo.GetDiscountRate
(
@CustomerType VARCHAR(20),
@OrderAmount DECIMAL(10,2)
)
RETURNS DECIMAL(5,2)
AS
BEGIN
DECLARE @Discount DECIMAL(5,2)
IF @CustomerType = 'Premium'
SET @Discount = 0.15
ELSE IF @CustomerType = 'Standard'
SET @Discount = 0.10
ELSE
SET @Discount = 0.05
IF @OrderAmount > 1000
SET @Discount = @Discount + 0.05
RETURN @Discount
END
GO
SELECT dbo.GetDiscountRate('Premium', 1200.00) as DiscountRate;
Ergebnis¶
DiscountRate |
|---|
0.20 |
Snowflake (SnowScript UDF)¶
CREATE OR REPLACE FUNCTION dbo.GetDiscountRate (CUSTOMERTYPE STRING, ORDERAMOUNT DECIMAL(10,2))
RETURNS DECIMAL(5, 2)
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/09/2025", "domain": "no-domain-provided", "migrationid": "QsqZARsvG3aeleeXZB43fg==" }}'
AS
$$
DECLARE
DISCOUNT DECIMAL(5, 2);
BEGIN
IF (:CUSTOMERTYPE = 'Premium') THEN
DISCOUNT := 0.15;
ELSEIF (:CUSTOMERTYPE = 'Standard') THEN
DISCOUNT := 0.10;
ELSE
DISCOUNT := 0.05;
END IF;
IF (:ORDERAMOUNT > 1000) THEN
DISCOUNT := :DISCOUNT + 0.05;
END IF;
RETURN :DISCOUNT;
END;
$$;
SELECT
dbo.GetDiscountRate('Premium', 1200.00) as DiscountRate;
Ergebnis¶
DISCOUNTRATE |
|---|
0.20 |
Funktion mit WHILE-Schleife¶
Funktionen mit WHILE-Schleifen für iterative Berechnungen.
SQL Server¶
CREATE FUNCTION dbo.Factorial
(
@Number INT
)
RETURNS BIGINT
AS
BEGIN
DECLARE @Result BIGINT = 1
DECLARE @Counter INT = 1
WHILE @Counter <= @Number
BEGIN
SET @Result = @Result * @Counter
SET @Counter = @Counter + 1
END
RETURN @Result
END
GO
SELECT dbo.Factorial(5) as FactorialResult;
Ergebnis¶
FactorialResult |
|---|
120 |
Snowflake (SnowScript UDF)¶
CREATE OR REPLACE FUNCTION dbo.Factorial (NUMBER INT)
RETURNS BIGINT
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/09/2025", "domain": "no-domain-provided", "migrationid": "QsqZARsvG3aeleeXZB43fg==" }}'
AS
$$
DECLARE
RESULT BIGINT := 1;
COUNTER INT := 1;
BEGIN
WHILE (:COUNTER <= :NUMBER) LOOP
RESULT := :RESULT * :COUNTER;
COUNTER := :COUNTER + 1;
END LOOP;
RETURN :RESULT;
END;
$$;
SELECT
dbo.Factorial(5) as FactorialResult;
Ergebnis¶
FACTORIALRESULT |
|---|
120 |
Zeichenfolgenbearbeitungsfunktion¶
Komplexe Zeichenfolgenoperationen mit Schleifen und bedingter Logik.
SQL Server¶
CREATE FUNCTION dbo.CleanPhoneNumber
(
@Phone VARCHAR(20)
)
RETURNS VARCHAR(10)
AS
BEGIN
DECLARE @Clean VARCHAR(10) = ''
DECLARE @i INT = 1
DECLARE @Char CHAR(1)
WHILE @i <= LEN(@Phone)
BEGIN
SET @Char = SUBSTRING(@Phone, @i, 1)
IF @Char BETWEEN '0' AND '9'
SET @Clean = @Clean + @Char
SET @i = @i + 1
END
RETURN @Clean
END
GO
SELECT dbo.CleanPhoneNumber('(555) 123-4567') as CleanPhone;
Ergebnis¶
CleanPhone |
|---|
5551234567 |
Snowflake (SnowScript UDF)¶
CREATE OR REPLACE FUNCTION dbo.CleanPhoneNumber (PHONE STRING)
RETURNS VARCHAR(10)
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/09/2025", "domain": "no-domain-provided", "migrationid": "QsqZARsvG3aeleeXZB43fg==" }}'
AS
$$
DECLARE
CLEAN VARCHAR(10) := '';
I INT := 1;
CHAR CHAR(1);
BEGIN
WHILE (:I <= LEN(:PHONE)) LOOP
CHAR := SUBSTRING(:PHONE, :I, 1);
IF (:CHAR BETWEEN '0' AND '9') THEN
CLEAN := :CLEAN + :CHAR;
END IF;
I := :I + 1;
END LOOP;
RETURN :CLEAN;
END;
$$;
SELECT
dbo.CleanPhoneNumber('(555) 123-4567') as CleanPhone;
Ergebnis¶
CLEANPHONE |
|---|
5551234567 |
CASE-Anweisungslogik¶
Funktionen mit CASE-Ausdrücke zur Kategorisierung.
SQL Server¶
CREATE FUNCTION dbo.GetGrade
(
@Score INT
)
RETURNS CHAR(1)
AS
BEGIN
DECLARE @Grade CHAR(1)
SET @Grade = CASE
WHEN @Score >= 90 THEN 'A'
WHEN @Score >= 80 THEN 'B'
WHEN @Score >= 70 THEN 'C'
WHEN @Score >= 60 THEN 'D'
ELSE 'F'
END
RETURN @Grade
END
GO
SELECT dbo.GetGrade(85) as Grade;
Ergebnis¶
Grade |
|---|
B |
Snowflake (SnowScript UDF)¶
CREATE OR REPLACE FUNCTION dbo.GetGrade (SCORE INT)
RETURNS CHAR(1)
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/09/2025", "domain": "no-domain-provided", "migrationid": "QsqZARsvG3aeleeXZB43fg==" }}'
AS
$$
DECLARE
GRADE CHAR(1);
BEGIN
CASE
WHEN :SCORE >= 90 THEN
GRADE := 'A';
WHEN :SCORE >= 80 THEN
GRADE := 'B';
WHEN :SCORE >= 70 THEN
GRADE := 'C';
WHEN :SCORE >= 60 THEN
GRADE := 'D';
ELSE
GRADE := 'F';
END;
RETURN :GRADE;
END;
$$;
SELECT
dbo.GetGrade(85) as Grade;
Ergebnis¶
GRADE |
|---|
B |
Select Into variable assingment¶
Functions using simple select into for variable assignment.
SQL Server¶
CREATE FUNCTION dbo.CalculatePrice
(
@BasePrice DECIMAL(10, 2),
@Quantity INT
)
RETURNS DECIMAL(10, 2)
AS
BEGIN
DECLARE @Discount DECIMAL(5, 2);
DECLARE @Subtotal DECIMAL(10, 2);
DECLARE @FinalPrice DECIMAL(10, 2);
SELECT @Discount = CASE
WHEN @Quantity >= 10 THEN 0.15
WHEN @Quantity >= 5 THEN 0.10
ELSE 0.05
END,
@Subtotal = @BasePrice * @Quantity;
SET @FinalPrice = @Subtotal * (1 - @Discount);
RETURN @FinalPrice;
END;
Ergebnis¶
CALCULATEPRICE(100, 3) |
|---|
285 |
Snowflake (SnowScript UDF)¶
CREATE OR REPLACE FUNCTION dbo.CalculatePrice (BASEPRICE DECIMAL(10, 2), QUANTITY INT)
RETURNS DECIMAL(10, 2)
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "11/26/2025", "domain": "no-domain-provided", "migrationid": "T8GaASfFsHeOffK4v3SnIQ==" }}'
AS
$$
DECLARE
DISCOUNT DECIMAL(5, 2);
SUBTOTAL DECIMAL(10, 2);
FINALPRICE DECIMAL(10, 2);
BEGIN
DISCOUNT := CASE
WHEN :QUANTITY >= 10 THEN 0.15
WHEN :QUANTITY >= 5 THEN 0.10
ELSE 0.05
END;
SUBTOTAL := :BASEPRICE * :QUANTITY;
FINALPRICE := :SUBTOTAL * (1 - :DISCOUNT);
RETURN :FINALPRICE;
END;
$$;
Ergebnis¶
CALCULATEPRICE(100, 3) |
|---|
285 |
Bekannte Probleme¶
Warnung
SnowConvert AI will not translate UDFs containing the following elements into SnowScripting UDFs, as these features are unsupported in SnowScripting UDFs:
Auf Datenbanktabellen zugreifen
Cursor verwenden
Andere UDFs aufrufen
Aggregat- oder Fensterfunktionen enthalten
DML-Operationen (INSERT/UPDATE/DELETE) ausführen
Resultsets zurückgeben
Zugehörige EWIs¶
[SSC-EWI-0067](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0067): UDF wurde in eine Snowflake-Prozedur umgewandelt, der Aufruf von Prozeduren innerhalb einer Abfrage wird nicht unterstützt.
SSC-EWI-0068: Die benutzerdefinierte Funktion wurde in eine Snowflake-Prozedur umgewandelt.
[SSC-EWI-0073](../../general/technical-documentation/issues-and-troubleshooting/conversion-issues/generalEWI. md#ssc-ewi-0073): Überprüfung der Funktionsäquivalenz ausstehend.