SnowConvert AI - SQL Server-Azure Synapse - 일반 언어 요소¶
이 섹션에서는 Transact-SQL의 일반 문에 대한 정보를 찾을 수 있습니다.
COLLATE¶
Applies to
SQL 서버
Azure 시냅스 분석
데이터 정렬의 변환은 지원되거나 지원되지 않을 수 있으므로 그 값에 따라 달라집니다.
현재 변환이 지원되는 언어는 다음과 같으며, 데이터 정렬에서 해당 언어가 발견되면 해당 언어에 해당하는 Snowflake로 변환됩니다.
SqlSever |
Snowflake |
|---|---|
Latin1_General |
EN |
Modern_Spanish |
ES |
프랑스어 |
FR |
언어가 위의 언어 중 하나가 아닌 경우 데이터 정렬에 설명이 추가됩니다.
또한 SqlServer 의 데이터 정렬에는 CI, CS, AI, 및 AS 같은 추가 사양이 제공되므로 이들만 지원되며, 그 이상이고 지원되지 않는 경우 결과에 설명이 표시됩니다.
원본¶
SELECT 'a' COLLATE Latin1_General_CI_AS;
SELECT 'a' COLLATE Modern_Spanish_CI_AS;
SELECT 'a' COLLATE French_CI_AS;
SELECT 'a' COLLATE Albanian_BIN;
SELECT 'a' COLLATE Latin1_General_CI_AS_WS;
SELECT 'a' COLLATE Latin1_General_CI_AS_KS_WS;
SELECT 'a' COLLATE Albanian_CI_AI;
예상¶
SELECT 'a' COLLATE 'EN-CI-AS';
SELECT 'a' COLLATE 'ES-CI-AS';
SELECT 'a' COLLATE 'FR-CI-AS';
SELECT 'a'
-- !!!RESOLVE EWI!!! /*** SSC-EWI-TS0077 - COLLATION Albanian_BIN NOT SUPPORTED ***/!!!
-- COLLATE Albanian_BIN
;
SELECT 'a' COLLATE 'EN-CI-AS' /*** SSC-FDM-TS0002 - COLLATION FOR VALUE WS NOT SUPPORTED ***/;
SELECT 'a' COLLATE 'EN-CI-AS' /*** SSC-FDM-TS0002 - COLLATION FOR VALUES KS,WS NOT SUPPORTED ***/;
SELECT 'a'
-- !!!RESOLVE EWI!!! /*** SSC-EWI-TS0077 - COLLATION Albanian_CI_AI NOT SUPPORTED ***/!!!
-- COLLATE Albanian_CI_AI
;
Create Table에서 데이터 정렬의 예를 보겠습니다
원본¶
CREATE TABLE TABLECOLLATE
(
COL1 VARCHAR COLLATE Latin1_General_CI_AS
);
예상¶
CREATE OR REPLACE TABLE TABLECOLLATE
(
COL1 VARCHAR COLLATE 'EN-CI-AS' /*** SSC-PRF-0002 - CASE INSENSITIVE COLUMNS CAN DECREASE THE PERFORMANCE OF QUERIES ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
;
보시다시피 Select 또는 Table 내에서 데이터 정렬의 변환은 동일합니다.
COMPUTED COLUMN¶
계산된 식을 변환할 수 없습니다.
Applies to
SQL 서버
Azure 시냅스 분석
설명¶
계산된 열의 식을 변환할 수 없습니다.
코드 예제¶
입력 코드:¶
CREATE TABLE [TestTable](
[Col1] AS (CONVERT ([REAL], ExpressionValue))
);
출력 코드:¶
CREATE OR REPLACE TABLE TestTable (
Col1 REAL AS (CAST(ExpressionValue AS REAL)) /*** SSC-FDM-TS0014 - COMPUTED COLUMN WAS TRANSFORMED TO ITS SNOWFLAKE EQUIVALENT, FUNCTIONAL EQUIVALENCE VERIFICATION PENDING. ***/
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
;
권장 사항¶
변환되지 않은 식에 수동 변경 사항을 추가합니다.
추가 지원이 필요한 경우 snowconvert-support@snowflake.com으로 이메일을 보내주세요.
관련 EWIs¶
SSC-FDM-TS0014: 계산된 열이 변환되었습니다.
OUTER APPLY¶
동등한 문으로 외부 apply 문 변환.
Applies to
SQL 서버
Azure 시냅스 분석
참고
출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.
설명¶
OUTER APPLY 를 지정하면 오른쪽 행 집합 식이 해당 행에 대해 빈 행 집합을 반환하더라도 왼쪽 행 집합의 각 행에 대해 1개의 행이 생성됩니다. (OUTER APPLY 정의)
구문¶
Apply_Operator :=
'CROSS' 'APPLY'
| 'OUTER' 'APPLY'.
Snowflake 등가성¶
지원되지 않는 문이 OUTER APPLY 에 있지만, 이에 상응하는 문이 LATERAL 입니다. 따라서 문에 대한 변환은 대체 솔루션을 사용하여 동일한 기능을 얻기 위해 수행됩니다.
그럼에도 불구하고 Snowflake의 LATERAL 문은 구문에서 두 가지 변형이 있습니다. 실제로 이 특정 변환에서는 INNER JOIN LATERAL 변형이 사용됩니다.
Snowflake의 INNER JOIN LATERAL 문법은 다음과 같습니다.
SELECT ...
FROM <left_hand_table_expression> INNER JOIN LATERAL ( <inline_view> )
...
참고
_<inline_view>_는 테이블 이름이 아니어야 합니다.
그리고 단일 LATERAL 문은 아래와 같습니다.
SELECT ...
FROM <left_hand_table_expression>, LATERAL ( <inline_view> )
...
샘플 소스¶
다음 예제는 OUTER APPLY 와 INNER JOIN LATERAL 사이의 일반적인 변환을 보여줍니다.
SQL 서버¶
SELECT p.ProjectName, e.ProjectName, e.FirstName
FROM Project p
OUTER APPLY (
SELECT
ProjectName,
FirstName,
LastName
FROM Employees e
) e;
출력¶
p.ProjectName |
e.ProjectName |
FirstName |
|---|---|---|
Project A |
Project A |
John |
Project A |
Project A |
Jane |
Project A |
Project B |
Michael |
Project B |
Project A |
John |
Project B |
Project A |
Jane |
Project B |
Project B |
Michael |
Project C |
Project A |
John |
Project C |
Project A |
Jane |
Project C |
Project B |
Michael |
Snowflake¶
SELECT
p.ProjectName,
e.ProjectName,
e.FirstName
FROM
Project p
INNER JOIN
LATERAL (
SELECT
ProjectName,
FirstName,
LastName
FROM
Employees e
) e;
출력¶
PROJECTNAME |
PROJECTNAME_2 |
FIRSTNAME |
|---|---|---|
Project A |
Project A |
John |
Project A |
Project A |
Jane |
Project A |
Project B |
Michael |
Project B |
Project A |
John |
Project B |
Project A |
Jane |
Project B |
Project B |
Michael |
Project C |
Project A |
John |
Project C |
Project A |
Jane |
Project C |
Project B |
Michael |
알려진 문제¶
변환은 입력된 내용을 그대로 옮기는 것이므로 몇 가지 제한이 있습니다.
TOP 및 WHERE 문을 검토하여 동작을 최적화할 수 있습니다.
문 끝에 상관관계 이름이 필요할 수 있습니다. Snowflake에서는 상관 관계 이름이 쿼리에 없는 경우 문제가 되지 않지만 기능이 변경되어 SQL 서버에서 허용되는 패턴의 일부를 형성하지 않을 수 있습니다.
SQL 서버¶
SELECT
SATT.UNIVERSAL_NAME
FROM
SAMPLE_ATLAS AS SATT
OUTER APPLY (
SELECT
TOP 1 UNIVERSAL_NAME,
INTERNATIONAL_NAME,
CODE_IDENTIFIER
FROM
SAMPLE_GLOBE AS SG
WHERE
SG.GLOBE_KEY = SATT.MbrPersGenKey
ORDER BY
GLOBE_KEY
);
변환 출력¶
SELECT
UNIVERSAL_NAME
FROM
SAMPLE_ATLAS
AS SATT
OUTER APPLY
/*** MSC-ERROR - MSCCP0001 - THE FOLLOWING SUBQUERY MATCHES AT LEAST ONE OF THE PATTERNS CONSIDERED INVALID AND MAY PRODUCE COMPILATION ERRORS ***/ (SELECT TOP 1
UNIVERSAL_NAME,
INTERNATIONAL_NAME,
CODE_IDENTIFIER
FROM
SAMPLE_GLOBE AS SG
WHERE
SG.GLOBE_KEY = SATT.MbrPersGenKey
ORDER BY GLOBE_KEY
);
지원되지 않는 특정 문은 모든 블록 코드를 설명할 수 있습니다(예: JSON 예시) .
SQL 서버¶
SELECT
SATT.UNIVERSAL_NAME
FROM
SAMPLE_ATLAS AS SATT
INNER JOIN LATERAL (
SELECT
TOP 1 UNIVERSAL_NAME,
INTERNATIONAL_NAME,
CODE_IDENTIFIER
FROM
SAMPLE_GLOBE AS SG
WHERE
SG.GLOBE_KEY = SATT.MbrPersGenKey
ORDER BY
GLOBE_KEY
);
변환 출력¶
SELECT
familyName,
c.givenName AS childGivenName,
c.firstName AS childFirstName,
p.givenName AS petName
FROM
Families f
LEFT OUTER JOIN
OPENJSON(f.doc) /*** MSC-WARNING - MSCEWI4030 - Equivalence from CROSS APPLY to LEFT OUTER JOIN must be checked. ***/;
-- ** MSC-ERROR - MSCEWI1001 - UNRECOGNIZED TOKEN ON LINE 7 OF THE SOURCE CODE. **
-- WITH (familyName nvarchar(100), children nvarchar(max) AS JSON)
-- CROSS APPLY OPENJSON(children)
-- WITH (givenName nvarchar(100), firstName nvarchar(100), pets nvarchar(max) AS JSON) as c
-- OUTER APPLY OPENJSON (pets)
-- WITH (givenName nvarchar(100)) as p
관련 EWIs¶
관련 EWIs 없음.
USE¶
Snowflake의 동등한 Transact-SQL USE 문
Applies to
SQL 서버
USE 문은 Snowflake에 해당하는 문이 있습니다. 문은 Snowflake의 USE DATABASE문으로 변환됩니다.
변환 예시¶
원본¶
USE [MY DATABASE]
출력¶
USE DATABASE "MY DATABASE";
데이터베이스 이름¶
USE 문에 지정된 데이터베이스 이름 은 대괄호 ([ ]) 내에 들어올 경우 변경될 수 있습니다. 첫 번째 괄호와 마지막 괄호는 _따옴표_로 바뀝니다. 예:
원본¶
[MYDATABASE]
[[[MYDATABASE]]
출력¶
"MYDATABASE"
"[[MYDATABASE]"
사용자 정의 데이터베이스¶
사용자가 변환 도구에 -d 매개 변수를 사용하여 모든 오브젝트에 적용할 사용자 정의 데이터베이스 이름을 지정하고 USE 문을 변환하려는 경우 데이터베이스 이름은 오브젝트가 아닌 USE 문에만 적용되어야 합니다. 이렇게 하면 사용 문에서 지정된 데이터베이스가 재정의됩니다. 예:
원본¶
-- Additional Params: -d MYCUSTOMDB
USE [MY DATABASE]
CREATE TABLE [TableName1].[TableName2](
[ColumnName1] varchar NULL
);
출력¶
-- Additional Params: -d MYCUSTOMDB
USE DATABASE MYCUSTOMDB;
CREATE OR REPLACE TABLE MYCUSTOMDB.TableName1.TableName2 (
ColumnName1 VARCHAR NULL
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"transact"}}'
;
Known Issues¶
문제가 발견되지 않았습니다.
관련 EWIs¶
관련 EWIs 없음.
EXECUTE¶
Applies to
SQL 서버
Azure 시냅스 분석
실행 또는 실행 문에 대한 변환은 Snowflake에서 지원되지 않지만, CALL 문으로 변환됩니다.
참고
출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.
입력¶
Exec db.sp1
출력¶
CALL db.sp1();
Execute에 대한 자세한 내용은 프로시저 내부 실행을 참조하세요.
PRINT¶
Applies to
SQL 서버
Azure 시냅스 분석
Print 문은 Snowflake에서 직접 지원되지 않지만, 가장 가까운 문인 SYSTEM$LOG_INFO 기본 제공 함수로 변환됩니다.
입력¶
PRINT 'My message';
출력(SnowScript 내부)¶
SYSTEM$LOG_INTO('My message');
출력(SnowScript 외부)¶
Print 문이 저장 프로시저 외부에서 사용되는 경우, SnowConvert AI UDP에서 호출해야 합니다.
CALL PUBLIC.LOG_INFO_UDP('My message');
메시지 로깅을 시작하려면 먼저 이벤트 테이블을 설정해야 합니다. 자세한 내용은 Snowflake Scripting에서 메시지 로깅을 참조하세요.
시스템 저장 프로시저¶
SP_EXECUTESQL¶
시스템 프로시저 SP_EXECUTESQL에 대한 변환 사양.
Applies to
SQL 서버
Azure 시냅스 분석
설명¶
SP_EXECUTESQL 시스템 저장 프로시저는 Transact-SQL 문 또는 여러 번 재사용할 수 있는 배치 또는 동적으로 빌드된 배치를 실행하는 데 사용됩니다. 문 또는 배치에는 임베디드 매개 변수가 포함될 수 있습니다.
이 기능은 EXECUTE IMMEDIATE 문과 임베디드 매개 변수에 대한 UDF(사용자 정의 함수)를 사용하여 Snowflake에서 에뮬레이션할 수 있습니다.
이 변환에 사용된 UDF(사용자 정의 함수)에 대한 자세한 내용은 TRANSFORM_SP_EXECUTE_SQL_STRING_UDF(STRING, STRING, ARRAY, ARRAY)를 확인하세요.
구문¶
Transact¶
sp_executesql [ @stmt = ] N'statement'
[
[ , [ @params = ] N'@parameter_name data_type [ { OUT | OUTPUT } ] [ , ...n ]' ]
[ , [ @param1 = ] 'value1' [ , ...n ] ]
]
샘플 소스 패턴¶
모든 패턴은 SP_EXECUTESQL 을 Snowflake의 EXECUTE IMMEDIATE 문으로 변환하고 임베디드 매개 변수를 사용할 때만 SQL 문자열이 실행되도록 수정했습니다.
경고
SSC-EWI-0030 (동적 SQL 사용)이 모든 패턴에 추가됩니다. SP_EXECUTESQL 변환은 Snowflake와 동일하지만, 이 문맥에서 EWI 는 SQL 문자열이 의도한 대로 실행되려면 수동 수정이 필요할 수 있음을 나타냅니다.
설정 데이터¶
Transact¶
CREATE TABLE PERSONS(
NAME VARCHAR(25),
ID INT,
AGE INT
);
-- DATA
INSERT INTO PERSONS VALUES ('John Smith', 1, 24);
INSERT INTO PERSONS VALUES ('John Doe', 2, 21);
INSERT INTO PERSONS VALUES ('Mary Keller', 3, 32);
INSERT INTO PERSONS VALUES ('Mundane Man', 4, 18);
Snowflake¶
CREATE OR REPLACE TABLE PERSONS (
NAME VARCHAR(25),
ID INT,
AGE INT
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
;
-- DATA
INSERT INTO PERSONS VALUES ('John Smith', 1, 24);
INSERT INTO PERSONS VALUES ('John Doe', 2, 21);
INSERT INTO PERSONS VALUES ('Mary Keller', 3, 32);
INSERT INTO PERSONS VALUES ('Mundane Man', 4, 18);
내장된 매개 변수 없음¶
임베디드 매개 변수가 사용되지 않는 경우 SP_EXECUTESQL 은 EXECUTE IMMEDIATE 문으로 변환되고 수정 없이 SQL 문자열을 사용합니다.
Transact¶
CREATE PROCEDURE SIMPLE_SINGLE_QUERY
AS
BEGIN
DECLARE @SQLString NVARCHAR(500);
SET @SQLString = N'SELECT * FROM PERSONS';
EXECUTE sp_executesql @SQLString;
END
GO
EXEC SIMPLE_SINGLE_QUERY;
결과¶
이름 |
ID |
AGE |
|---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Mary Keller |
3 |
32 |
Mundane Man |
4 |
18 |
Snowflake¶
CREATE OR REPLACE PROCEDURE SIMPLE_SINGLE_QUERY ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
SQLSTRING VARCHAR(500);
ProcedureResultSet RESULTSET;
BEGIN
SQLSTRING := 'SELECT
*
FROM
PERSONS;';
ProcedureResultSet := (
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :SQLSTRING
);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL SIMPLE_SINGLE_QUERY();
결과¶
이름 |
ID |
AGE |
|---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Mary Keller |
3 |
32 |
Mundane Man |
4 |
18 |
데이터 바인딩을 위한 내장 매개 변수 포함¶
데이터 바인딩을 위한 임베디드 매개 변수의 경우, SP_EXECUTESQL은 EXECUTE IMMEDIATE 문으로 변환되고 SQL 문자열은 TRANSFORM_SP_EXECUTE_SQL_STRING_UDF를 통해 수정됩니다.
EXECUTE IMMEDIATE 의 결과는 ProcedureResultSet 변수에 할당되고 나중에 TABLE(ProcedureResultSet) 로 반환됩니다.
Transact¶
CREATE PROCEDURE QUERY_WITH_DATA_BINDING_PARAMS
AS
BEGIN
DECLARE @IntVariable INT;
DECLARE @SQLString NVARCHAR(500);
DECLARE @ParmDefinition NVARCHAR(500);
SET @IntVariable = 21;
SET @SQLString = N'SELECT * FROM PERSONS WHERE AGE = @age';
SET @ParmDefinition = N'@age INT';
EXECUTE sp_executesql @SQLString, @ParmDefinition, @age = @IntVariable;
END
GO
EXEC QUERY_WITH_DATA_BINDING_PARAMS;
결과¶
이름 |
ID |
AGE |
|---|---|---|
John Doe |
2 |
21 |
Snowflake¶
CREATE OR REPLACE PROCEDURE QUERY_WITH_DATA_BINDING_PARAMS ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
INTVARIABLE INT;
SQLSTRING VARCHAR(500);
PARMDEFINITION VARCHAR(500);
ProcedureResultSet RESULTSET;
BEGIN
INTVARIABLE := 21;
SQLSTRING := 'SELECT
*
FROM
PERSONS
WHERE
AGE = @age;';
PARMDEFINITION := '@age INT';
ProcedureResultSet := (
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE TRANSFORM_SP_EXECUTE_SQL_STRING_UDF(:SQLSTRING, :PARMDEFINITION, ARRAY_CONSTRUCT('AGE'), ARRAY_CONSTRUCT(:INTVARIABLE))
);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL QUERY_WITH_DATA_BINDING_PARAMS();
결과¶
이름 |
ID |
AGE |
|---|---|---|
John Doe |
2 |
21 |
내장된 OUTPUT 매개 변수 포함¶
임베디드 OUTPUT 매개 변수의 경우 SP_EXECUTESQL 은EXECUTE IMMEDIATE 문으로 변환되고 SQL 문자열은 TRANSFORM_SP_EXECUTE_SQL_STRING_UDF 을 통해 수정됩니다.
또한 SELECT $1, ..., $n INTO :outputParam1, ..., :outputParamN FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())) 이 각 열의 결과에 해당 OUTPUT 매개 변수에 추가됩니다.
경고
SSC-FDM-TS0028 은 SELECT INTO 문에 추가됩니다. INTO 절의 매개 변수는 원래 SQL 문자열에 할당된 것과 동일한 순서로 표시되어야 합니다.
그렇지 않으면 이 필수 권한을 충족하기 위해 수동으로 변경해야 합니다.
Transact¶
CREATE PROCEDURE QUERY_WITH_OUTPUT_PARAMS
AS
BEGIN
DECLARE @SQLString NVARCHAR(500);
DECLARE @ParamDefinition NVARCHAR(500);
DECLARE @MaxAge INT;
SET @SQLString = N'SELECT @MaxAgeOUT = max(AGE) FROM PERSONS';
SET @ParamDefinition = N'@MaxAgeOUT INT OUTPUT';
EXECUTE sp_executesql @SQLString, @ParamDefinition, @MaxAgeOUT = @MaxAge OUTPUT;
SELECT @MaxAge;
END
GO
EXEC QUERY_WITH_OUTPUT_PARAMS;
결과¶
<anonymous> |
|---|
32 |
Snowflake¶
CREATE OR REPLACE PROCEDURE QUERY_WITH_OUTPUT_PARAMS ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "11/27/2024", "domain": "test" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
SQLSTRING VARCHAR(500);
PARAMDEFINITION VARCHAR(500);
MAXAGE INT;
ProcedureResultSet RESULTSET;
BEGIN
SQLSTRING := 'SELECT
MAX(AGE) FROM
PERSONS;';
PARAMDEFINITION := '@MaxAgeOUT INT OUTPUT';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE TRANSFORM_SP_EXECUTE_SQL_STRING_UDF(:SQLSTRING, :PARAMDEFINITION, ARRAY_CONSTRUCT('MAXAGEOUT'), ARRAY_CONSTRUCT(:MAXAGE));
--** SSC-FDM-TS0028 - OUTPUT PARAMETERS MUST HAVE THE SAME ORDER AS THEY APPEAR IN THE EXECUTED CODE **
SELECT
$1
INTO
:MAXAGE
FROM
TABLE(RESULT_SCAN(LAST_QUERY_ID()));
ProcedureResultSet := (
SELECT
:MAXAGE);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL QUERY_WITH_OUTPUT_PARAMS();
결과¶
:MAXAGE::NUMBER(38,0) |
|---|
32 |
임베디드 OUTPUT 매개 변수 및 데이터 바인딩 모두 포함¶
변환은 OUTPUT 매개 변수만 변환하는 것과 동일합니다.
Transact¶
CREATE PROCEDURE QUERY_WITH_BOTH_PARAMS
AS
BEGIN
DECLARE @AgeVariable INT;
DECLARE @IdVariable INT;
DECLARE @SQLString NVARCHAR(500);
DECLARE @ParmDefinition NVARCHAR(500);
DECLARE @MaxAge INT;
DECLARE @MaxId INT;
SET @AgeVariable = 30;
SET @IdVariable = 100;
SET @SQLString = N'SELECT @MaxAgeOUT = max(AGE), @MaxIdOut = max(ID) FROM PERSONS WHERE AGE < @age AND ID < @id;';
SET @ParmDefinition = N'@age INT, @id INT, @MaxAgeOUT INT OUTPUT, @MaxIdOUT INT OUTPUT';
EXECUTE sp_executesql @SQLString, @ParmDefinition, @age = @AgeVariable, @id = @IdVariable, @MaxAgeOUT = @MaxAge OUTPUT, @MaxIdOUT = @MaxId OUTPUT;
SELECT @MaxAge, @MaxId;
END
GO
EXEC QUERY_WITH_BOTH_PARAMS;
결과¶
<anonymous> |
<anonymous> |
|---|---|
24 |
4 |
Snowflake¶
CREATE OR REPLACE PROCEDURE QUERY_WITH_BOTH_PARAMS ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
AGEVARIABLE INT;
IDVARIABLE INT;
SQLSTRING VARCHAR(500);
PARMDEFINITION VARCHAR(500);
MAXAGE INT;
MAXID INT;
ProcedureResultSet RESULTSET;
BEGIN
AGEVARIABLE := 30;
IDVARIABLE := 100;
SQLSTRING := 'SELECT
MAX(AGE),
MAX(ID) FROM
PERSONS
WHERE
AGE < @age AND ID < @id;';
PARMDEFINITION := '@age INT, @id INT, @MaxAgeOUT INT OUTPUT, @MaxIdOUT INT OUTPUT';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE TRANSFORM_SP_EXECUTE_SQL_STRING_UDF(:SQLSTRING, :PARMDEFINITION, ARRAY_CONSTRUCT('AGE', 'ID', 'MAXAGEOUT', 'MAXIDOUT'), ARRAY_CONSTRUCT(:AGEVARIABLE, :IDVARIABLE, :MAXAGE, :MAXID));
--** SSC-FDM-TS0028 - OUTPUT PARAMETERS MUST HAVE THE SAME ORDER AS THEY APPEAR IN THE EXECUTED CODE **
SELECT
$1,
$2
INTO
:MAXAGE,
:MAXID
FROM
TABLE(RESULT_SCAN(LAST_QUERY_ID()));
ProcedureResultSet := (
SELECT
:MAXAGE,
:MAXID);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL QUERY_WITH_BOTH_PARAMS();
결과¶
:MAXAGE::NUMBER(38,0) |
:MAXID::NUMBER(38,0) |
|---|---|
24 |
4 |
정의 순서가 아닌 매개 변수¶
이 패턴은 이전 패턴과 동일한 규칙을 따릅니다. TRANSFORM_SP_EXECUTE_SQL_STRING_UDF 매개 변수 값을 올바른 순서로 바꿉니다.
Transact¶
CREATE PROCEDURE QUERY_PARAMS_NOT_IN_ORDER_OF_DEF
AS
BEGIN
DECLARE @AgeVariable INT;
DECLARE @IdVariable INT;
DECLARE @SQLString NVARCHAR(500);
DECLARE @ParmDefinition NVARCHAR(500);
DECLARE @MaxAge INT;
DECLARE @MaxId INT;
SET @AgeVariable = 30;
SET @IdVariable = 100;
SET @SQLString = N'SELECT @MaxAgeOUT = max(AGE), @MaxIdOut = max(ID) FROM PERSONS WHERE AGE < @age AND ID < @id;';
SET @ParmDefinition = N'@age INT, @id INT, @MaxAgeOUT INT OUTPUT, @MaxIdOUT INT OUTPUT';
EXECUTE sp_executesql @SQLString, @ParmDefinition, @id = @IdVariable, @MaxAgeOUT = @MaxAge OUTPUT, @age = @AgeVariable, @MaxIdOUT = @MaxId OUTPUT;
SELECT @MaxAge, @MaxId;
END
GO
EXEC QUERY_PARAMS_NOT_IN_ORDER_OF_DEF;
CREATE PROCEDURE QUERY_PARAMS_NOT_IN_ORDER_OF_DEF_2
AS
BEGIN
DECLARE @AgeVariable INT;
DECLARE @IdVariable INT;
DECLARE @SQLString NVARCHAR(500);
DECLARE @ParmDefinition NVARCHAR(500);
DECLARE @MaxAge INT;
DECLARE @MaxId INT;
SET @AgeVariable = 30;
SET @IdVariable = 100;
SET @SQLString = N'SELECT @MaxAgeOUT = max(AGE), @MaxIdOut = max(ID) FROM PERSONS WHERE AGE < @age AND ID < @id;';
SET @ParmDefinition = N'@age INT, @id INT, @MaxAgeOUT INT OUTPUT, @MaxIdOUT INT OUTPUT';
EXECUTE sp_executesql @SQLString, @ParmDefinition, @AgeVariable, @MaxAgeOUT = @MaxAge OUTPUT, @id = @IdVariable, @MaxIdOUT = @MaxId OUTPUT;
SELECT @MaxAge, @MaxId;
END
GO
EXEC QUERY_PARAMS_NOT_IN_ORDER_OF_DEF_2;
결과¶
<anonymous> |
<anonymous> |
|---|---|
24 |
4 |
<anonymous> |
<anonymous> |
|---|---|
24 |
4 |
Snowflake¶
CREATE OR REPLACE PROCEDURE QUERY_PARAMS_NOT_IN_ORDER_OF_DEF ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
AGEVARIABLE INT;
IDVARIABLE INT;
SQLSTRING VARCHAR(500);
PARMDEFINITION VARCHAR(500);
MAXAGE INT;
MAXID INT;
ProcedureResultSet RESULTSET;
BEGIN
AGEVARIABLE := 30;
IDVARIABLE := 100;
SQLSTRING := 'SELECT
MAX(AGE),
MAX(ID) FROM
PERSONS
WHERE
AGE < @age AND ID < @id;';
PARMDEFINITION := '@age INT, @id INT, @MaxAgeOUT INT OUTPUT, @MaxIdOUT INT OUTPUT';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE TRANSFORM_SP_EXECUTE_SQL_STRING_UDF(:SQLSTRING, :PARMDEFINITION, ARRAY_CONSTRUCT('ID', 'MAXAGEOUT', 'AGE', 'MAXIDOUT'), ARRAY_CONSTRUCT(:IDVARIABLE, :MAXAGE, :AGEVARIABLE, :MAXID));
--** SSC-FDM-TS0028 - OUTPUT PARAMETERS MUST HAVE THE SAME ORDER AS THEY APPEAR IN THE EXECUTED CODE **
SELECT
$1,
$2
INTO
:MAXAGE,
:MAXID
FROM
TABLE(RESULT_SCAN(LAST_QUERY_ID()));
ProcedureResultSet := (
SELECT
:MAXAGE,
:MAXID);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL QUERY_PARAMS_NOT_IN_ORDER_OF_DEF();
CREATE OR REPLACE PROCEDURE QUERY_PARAMS_NOT_IN_ORDER_OF_DEF_2 ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
AGEVARIABLE INT;
IDVARIABLE INT;
SQLSTRING VARCHAR(500);
PARMDEFINITION VARCHAR(500);
MAXAGE INT;
MAXID INT;
ProcedureResultSet RESULTSET;
BEGIN
AGEVARIABLE := 30;
IDVARIABLE := 100;
SQLSTRING := 'SELECT
MAX(AGE),
MAX(ID) FROM
PERSONS
WHERE
AGE < @age AND ID < @id;';
PARMDEFINITION := '@age INT, @id INT, @MaxAgeOUT INT OUTPUT, @MaxIdOUT INT OUTPUT';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE TRANSFORM_SP_EXECUTE_SQL_STRING_UDF(:SQLSTRING, :PARMDEFINITION, ARRAY_CONSTRUCT('', 'MAXAGEOUT', 'ID', 'MAXIDOUT'), ARRAY_CONSTRUCT(:AGEVARIABLE, :MAXAGE, :IDVARIABLE, :MAXID));
--** SSC-FDM-TS0028 - OUTPUT PARAMETERS MUST HAVE THE SAME ORDER AS THEY APPEAR IN THE EXECUTED CODE **
SELECT
$1,
$2
INTO
:MAXAGE,
:MAXID
FROM
TABLE(RESULT_SCAN(LAST_QUERY_ID()));
ProcedureResultSet := (
SELECT
:MAXAGE,
:MAXID);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL QUERY_PARAMS_NOT_IN_ORDER_OF_DEF_2();
결과¶
:MAXAGE::NUMBER(38,0) |
:MAXID::NUMBER(38,0) |
|---|---|
24 |
4 |
:MAXAGE::NUMBER(38,0) |
:MAXID::NUMBER(38,0) |
|---|---|
24 |
4 |
직접 값 실행¶
이 변환은 변수를 사용하는 대신 값을 직접 할당하는 경우도 처리합니다.
Transact¶
CREATE PROCEDURE QUERY_WITH_DIRECT_PARAMS_VALUES_ALL
AS
BEGIN
DECLARE @MaxAge INT;
DECLARE @MaxId INT;
EXECUTE sp_executesql
N'SELECT @MaxAgeOUT = max(AGE), @MaxIdOut = max(ID) FROM PERSONS WHERE ID < @id AND AGE < @age;',
N'@age INT, @id INT, @MaxAgeOUT INT OUTPUT, @MaxIdOUT INT OUTPUT',
30,
100,
@MaxAge OUTPUT,
@MaxId OUTPUT;
SELECT @MaxAge, @MaxId;
END
GO
EXEC QUERY_WITH_DIRECT_PARAMS_VALUES_ALL;
결과¶
<anonymous> |
<anonymous> |
|---|---|
24 |
4 |
Snowflake¶
CREATE OR REPLACE PROCEDURE QUERY_WITH_DIRECT_PARAMS_VALUES_ALL ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/07/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
MAXAGE INT;
MAXID INT;
ProcedureResultSet RESULTSET;
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE TRANSFORM_SP_EXECUTE_SQL_STRING_UDF('SELECT
MAX(AGE),
MAX(ID) FROM
PERSONS
WHERE
ID < @id AND AGE < @age;', '@age INT, @id INT, @MaxAgeOUT INT OUTPUT, @MaxIdOUT INT OUTPUT', ARRAY_CONSTRUCT('', '', '', ''), ARRAY_CONSTRUCT(
30,
100, :MAXAGE, :MAXID));
--** SSC-FDM-TS0028 - OUTPUT PARAMETERS MUST HAVE THE SAME ORDER AS THEY APPEAR IN THE EXECUTED CODE **
SELECT
$1,
$2
INTO
:MAXAGE,
:MAXID
FROM
TABLE(RESULT_SCAN(LAST_QUERY_ID()));
ProcedureResultSet := (
SELECT
:MAXAGE,
:MAXID);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL QUERY_WITH_DIRECT_PARAMS_VALUES_ALL();
결과¶
:MAXAGE::NUMBER(38,0) |
:MAXID::NUMBER(38,0) |
|---|---|
24 |
4 |
SQL 동적으로 작성된 문자열¶
이 패턴은 이전 패턴과 동일한 규칙을 따릅니다. 그러나 SQL 문자열이 매개 변수가 포함되거나 포함되지 않은 단순한 단일 쿼리가 아닌 경우 EXECUTE IMMEDIATE 문의 결과를 할당하지 않을 수 있습니다.
또한, SnowConvert AI가 SELECT 문이 실행될 것이라는 사실을 올바르게 식별하려면 SQL 문자열은 리터럴 값 'SELECT'로 시작해야 합니다.
Transact¶
CREATE PROCEDURE DYNAMIC_WITH_PARAMS
AS
BEGIN
DECLARE @IntVariable INT;
DECLARE @SQLString NVARCHAR(500);
DECLARE @ParmDefinition NVARCHAR(500);
DECLARE @where_clause nvarchar(100);
SET @where_clause = 'WHERE AGE = @age';
SET @IntVariable = 21;
SET @SQLString = N'SELECT * FROM PERSONS ' + @where_clause;
SET @ParmDefinition = N'@age INT';
EXECUTE sp_executesql @SQLString, @ParmDefinition, @age = @IntVariable;
END
GO
EXEC DYNAMIC_WITH_PARAMS;
결과¶
이름 |
ID |
AGE |
|---|---|---|
John Doe |
2 |
21 |
Snowflake¶
CREATE OR REPLACE PROCEDURE DYNAMIC_WITH_PARAMS ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
INTVARIABLE INT;
SQLSTRING VARCHAR(500);
PARMDEFINITION VARCHAR(500);
WHERE_CLAUSE VARCHAR(100);
ProcedureResultSet RESULTSET;
BEGIN
WHERE_CLAUSE := 'WHERE AGE = @age';
INTVARIABLE := 21;
SQLSTRING := 'SELECT
*
FROM
PERSONS ' || :WHERE_CLAUSE || ';';
PARMDEFINITION := '@age INT';
ProcedureResultSet := (
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE TRANSFORM_SP_EXECUTE_SQL_STRING_UDF(:SQLSTRING, :PARMDEFINITION, ARRAY_CONSTRUCT('AGE'), ARRAY_CONSTRUCT(:INTVARIABLE))
);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL DYNAMIC_WITH_PARAMS();
결과¶
이름 |
ID |
AGE |
|---|---|---|
John Doe |
2 |
21 |
여러 결과 세트 반환하기¶
Snowflake Scripting 프로시저에서는 프로시저당 1개의 결과 세트만 반환할 수 있습니다.
Transact-SQL 동작을 복제하려면 2개 이상의 결과 세트가 반환되어야 하는 경우 임시 테이블에 저장됩니다. Snowflake Scripting 프로시저는 임시 테이블의 이름이 포함된 배열을 반환합니다. 자세한 내용은 SSC-FDM-0020 섹션을 참조하십시오.
Transact¶
CREATE PROCEDURE WITH_MULTIPLE_RETURNS
AS
BEGIN
DECLARE @SQLString NVARCHAR(500);
DECLARE @ParmDefinition NVARCHAR(500);
SET @SQLString = N'SELECT * FROM PERSONS WHERE AGE = @age';
SET @ParmDefinition = N'@age INT';
EXECUTE sp_executesql @SQLString, @ParmDefinition, @age = 21;
SET @SQLString = N'INSERT INTO PERSONS VALUES (''INSERT FIRST'', 1200, 230);';
EXECUTE sp_executesql @SQLString;
SET @SQLString = N'SELECT * FROM PERSONS';
EXECUTE sp_executesql @SQLString;
END
GO
EXECUTE WITH_MULTIPLE_RETURNS;
결과¶
이름 |
ID |
AGE |
|---|---|---|
John Doe |
2 |
21 |
이름 |
ID |
AGE |
|---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Mary Keller |
3 |
32 |
Mundane Man |
4 |
18 |
INSERT FIRST |
1200 |
230 |
Snowflake¶
CREATE OR REPLACE PROCEDURE WITH_MULTIPLE_RETURNS ()
RETURNS ARRAY
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/07/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
SQLSTRING VARCHAR(500);
PARMDEFINITION VARCHAR(500);
ProcedureResultSet1 VARCHAR;
ProcedureResultSet2 VARCHAR;
return_arr ARRAY := array_construct();
BEGIN
SQLSTRING := 'SELECT
*
FROM
PERSONS
WHERE
AGE = @age;';
PARMDEFINITION := '@age INT';
ProcedureResultSet1 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE TRANSFORM_SP_EXECUTE_SQL_STRING_UDF(:SQLSTRING, :PARMDEFINITION, ARRAY_CONSTRUCT('AGE'), ARRAY_CONSTRUCT(21));
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:ProcedureResultSet1) AS
SELECT
*
FROM
TABLE(RESULT_SCAN(LAST_QUERY_ID()));
return_arr := array_append(return_arr, :ProcedureResultSet1);
SQLSTRING := 'INSERT INTO PERSONS VALUES ('INSERT FIRST', 1200, 230);';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :SQLSTRING;
SQLSTRING := 'SELECT
*
FROM
PERSONS;';
ProcedureResultSet2 := 'RESULTSET_' || REPLACE(UPPER(UUID_STRING()), '-', '_');
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :SQLSTRING;
CREATE OR REPLACE TEMPORARY TABLE IDENTIFIER(:ProcedureResultSet2) AS
SELECT
*
FROM
TABLE(RESULT_SCAN(LAST_QUERY_ID()));
return_arr := array_append(return_arr, :ProcedureResultSet2);
--** SSC-FDM-0020 - MULTIPLE RESULT SETS ARE RETURNED IN TEMPORARY TABLES **
RETURN return_arr;
END;
$$;
CALL WITH_MULTIPLE_RETURNS();
결과¶
WITH_MULTIPLE_RETURNS |
|---|
[ “RESULTSET_88C35D7A_1E5B_455D_97A4_247806E583A5”, “RESULTSET_B2345B61_A015_43CB_BA11_6D3E013EF262” ] |
Known Issues¶
1. Invalid code is detected¶
SP_EXECUTESQL은 SQL 문자열 내부에서 둘 이상의 SQL 문을 실행할 수 있습니다. 또한 Snowflake는 여러 SQL 문을 실행하도록 지원하지만 BEGIN ... END 블록으로 묶어야 합니다. 또한, BEGIN ... END 블록에서 여러 문을 실행할 때 EXECUTE IMMEDIATE는 결과 세트를 반환하지 않습니다. 이러한 사례에 대한 변환은 SnowConvert AI에서 아직 지원되지 않습니다. 자세한 내용은 SSC-EWI-0030을 참조하세요.
따라서 이 경우가 감지되면 변환된 코드에서 EXECUTE IMMEDIATE 은 ProcedureResultSet 에 할당되지 않습니다.
Transact¶
CREATE PROCEDURE WITH_INVALID_CODE_DETECTED
AS
BEGIN
DECLARE @SQLString NVARCHAR(500);
SET @SQLString = N'INSERT INTO PERSONS VALUES (''INSERT FIRST'', 1200, 230); SELECT * FROM PERSONS;';
EXECUTE sp_executesql @SQLString;
END
GO
EXEC WITH_INVALID_CODE_DETECTED;
결과¶
이름 |
ID |
AGE |
|---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Mary Keller |
3 |
32 |
Mundane Man |
4 |
18 |
INSERT FIRST |
1200 |
230 |
Snowflake¶
CREATE OR REPLACE PROCEDURE WITH_INVALID_CODE_DETECTED ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
SQLSTRING VARCHAR(500);
BEGIN
SQLSTRING := 'INSERT INTO PERSONS VALUES ('INSERT FIRST', 1200, 230); SELECT
*
FROM
PERSONS;';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :SQLSTRING;
END;
$$;
CALL WITH_INVALID_CODE_DETECTED();
결과¶
000006 (0A000): Uncaught exception of type 'STATEMENT_ERROR' on line 10 at position 4 : Multiple SQL statements in a single API call are not supported; use one API call per statement instead.
2. Valid or Invalid code is not detected¶
SQL 문자열이 연결을 통해 동적으로 빌드되면 SnowConvert AI는 실행할 문을 감지하지 못할 수 있습니다. 따라서 변환된 코드에서 EXECUTE IMMEDIATE가 ProcedureResultSet에 할당되지 않습니다.
Transact¶
CREATE PROCEDURE WITH_INVALID_CODE_NOT_DETECTED
AS
BEGIN
DECLARE @SQLString NVARCHAR(500);
DECLARE @SQLInsert NVARCHAR(500);
SET @SQLInsert = N'INSERT INTO PERSONS VALUES (''INSERT FIRST'', 1200, 230)';
SET @SQLString = @SQLInsert + N'SELECT * FROM PERSONS;';
EXECUTE sp_executesql @SQLString;
END
GO
EXEC WITH_INVALID_CODE_NOT_DETECTED;
결과¶
이름 |
ID |
AGE |
|---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Mary Keller |
3 |
32 |
Mundane Man |
4 |
18 |
INSERT FIRST |
1200 |
230 |
Snowflake¶
CREATE OR REPLACE PROCEDURE WITH_INVALID_CODE_NOT_DETECTED ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
SQLSTRING VARCHAR(500);
SQLINSERT VARCHAR(500);
BEGIN
SQLINSERT := 'INSERT INTO PERSONS VALUES ('INSERT FIRST', 1200, 230);';
SQLSTRING := :SQLINSERT || 'SELECT * FROM PERSONS;';
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :SQLSTRING;
END;
$$;
CALL WITH_INVALID_CODE_NOT_DETECTED();
결과¶
000006 (0A000): Uncaught exception of type 'STATEMENT_ERROR' on line 10 at position 4 : Multiple SQL statements in a single API call are not supported; use one API call per statement instead.
3. Invalid code is mistaken as valid¶
SQL 문자열이 SELECT 문으로 시작되고 뒤에 더 많은 문이 오는 경우 SnowConvert AI는 이를 유효한 코드로 감지하고 EXECUTE IMMEDIATE의 결과를 ProcedureResultSet에 할당하려고 시도합니다. 이로 인해 컴파일 오류가 발생합니다. 자세한 내용은 SSC-EWI-0030을 참조하세요.
Transact¶
CREATE PROCEDURE WITH_INVALID_CODE_MISTAKEN_AS_VALID
AS
BEGIN
DECLARE @SQLString NVARCHAR(500);
SET @SQLString = N'SELECT * FROM PERSONS; SELECT * FROM PERSONS;';
EXECUTE sp_executesql @SQLString;
END
GO
EXEC WITH_INVALID_CODE_MISTAKEN_AS_VALID;
결과¶
이름 |
ID |
AGE |
|---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Mary Keller |
3 |
32 |
Mundane Man |
4 |
18 |
이름 |
ID |
AGE |
|---|---|---|
John Smith |
1 |
24 |
John Doe |
2 |
21 |
Mary Keller |
3 |
32 |
Mundane Man |
4 |
18 |
Snowflake¶
CREATE OR REPLACE PROCEDURE WITH_INVALID_CODE_MISTAKEN_AS_VALID ()
RETURNS TABLE()
LANGUAGE SQL
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "transact", "convertedOn": "10/04/2024" }}'
EXECUTE AS CALLER
AS
$$
DECLARE
SQLSTRING VARCHAR(500);
ProcedureResultSet RESULTSET;
BEGIN
SQLSTRING := 'SELECT
*
FROM
PERSONS; SELECT
*
FROM
PERSONS;';
ProcedureResultSet := (
!!!RESOLVE EWI!!! /*** SSC-EWI-0030 - THE STATEMENT BELOW HAS USAGES OF DYNAMIC SQL. ***/!!!
EXECUTE IMMEDIATE :SQLSTRING
);
RETURN TABLE(ProcedureResultSet);
END;
$$;
CALL WITH_INVALID_CODE_MISTAKEN_AS_VALID();
결과¶
000006 (0A000): Uncaught exception of type 'STATEMENT_ERROR' on line 10 at position 4 : Multiple SQL statements in a single API call are not supported; use one API call per statement instead.
관련 EWIs¶
SSC-EWI-0030: 아래 문에는 동적 SQL 의 사용법이 설명되어 있습니다.
SSC-FDM-TS0028: 출력 매개 변수는 실행된 코드에 표시되는 순서와 동일해야 합니다.
SSC-FDM-0020: 여러 결과 세트가 임시 테이블에 반환됩니다.
SP_RENAME¶
SQL Server에서 특정 오브젝트의 이름을 바꾸는 저장 프로시저
Applies to
SQL 서버
Azure 시냅스 분석
특정 시나리오에서는 SP_RENAME 시스템 저장소 프로시저를 Snowflake에서 에뮬레이션할 수 있습니다. 일반적으로 ALTER TABLE 및 원래 매개 변수와 동적 문을 사용하는 EXECUTE IMMEDIATE를 통해 동등한 기능을 얻을 수 있습니다.
테이블 변환 예제¶
원본¶
EXEC sp_rename 'TABLE1', 'TABLENEW1'
출력¶
EXECUTE IMMEDIATE 'ALTER TABLE TABLE1 RENAME TO TABLENEW1';
원본¶
DECLARE @varname1 nvarchar(50) = 'previous_name'
DECLARE @varname2 nvarchar(50) = 'newer_name'
EXEC sp_rename @varname1, @varname2
출력¶
DECLARE
VARNAME1 VARCHAR(50) := 'previous_name';
VARNAME2 VARCHAR(50) := 'newer_name';
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE ' || :VARNAME1 || ' RENAME TO ' || :VARNAME2;
END;
열의 변환 예제¶
원본¶
EXEC sp_rename 'sample_BACKUP_2.column_old', 'column_new', 'COLUMN'
EXEC sp_rename 'database1.sample_BACKUP_3.column_old', 'column_new', 'COLUMN'
출력¶
EXECUTE IMMEDIATE 'ALTER TABLE sample_BACKUP_2 RENAME COLUMN column_old TO column_new';
EXECUTE IMMEDIATE 'ALTER TABLE database1.sample_BACKUP_3 RENAME COLUMN column_old TO column_new';
원본¶
DECLARE @oldColumnName nvarchar(50) = 'previous_name'
DECLARE @newColumnName nvarchar(50) = 'newer_name'
DECLARE @tableName nvarchar(50) = 'TABLE'
EXEC sp_rename @objname = @tableName + '.' + @oldColumnName, @newname = @newColumnName, @objtype = 'COLUMN';
출력¶
DECLARE
OLDCOLUMNNAME VARCHAR(50) := 'previous_name';
NEWCOLUMNNAME VARCHAR(50) := 'newer_name';
TABLENAME VARCHAR(50) := 'TABLE';
BEGIN
!!!RESOLVE EWI!!! /*** SSC-EWI-TS0075 - TRANSLATION FOR BUILT-IN PROCEDURE 'SP_RENAME' IS NOT CURRENTLY SUPPORTED. ***/!!!
EXEC sp_rename OBJNAME = :TABLENAME || '.' || :OLDCOLUMNNAME, NEWNAME = :NEWCOLUMNNAME, OBJTYPE = 'COLUMN';
END;
관련 EWIs¶
SSC-EWI-TS0075: 기본 제공 프로시저에 대한 변환은 현재 지원되지 않습니다.