JavaScript 存储过程 API¶
本主题介绍 JavaScript API for Snowflake 存储过程。此 API 由 JavaScript 对象和这些对象中的方法组成。
本主题内容:
对象:snowflake
¶
默认情况下,存储过程中的 JavaScript 代码可以访问 snowflake
对象;您不需要创建此对象。此对象包含存储过程 API 中的方法。例如:
create procedure stproc1() returns string not null language javascript as -- "$$" is the delimiter for the beginning and end of the stored procedure. $$ // The "snowflake" object is provided automatically in each stored procedure. // You don't need to create it. // ||||||||| // vvvvvvvvv var statement = snowflake.createStatement(...); ... $$ ;
使用存储过程 中提供了更丰富的代码示例。
常量¶
无。
方法¶
- addEvent(name[, attributes])¶
添加用于跟踪的事件。
有关使用 JavaScript 时的跟踪事件的更多信息,请参阅 使用 JavaScript 发出跟踪事件
- 参数:
name
要添加的事件的名称。
attributes
指定要与事件关联的属性的对象。
- 错误:
如果出现以下情况,则会引发 JavaScript 错误:
name
不是字符串。实参为零个或两个以上。
- 示例:
添加一个具有
score
和pass
属性的my_event
事件。snowflake.addEvent('my_event', {'score': 89, 'pass': true});
- createStatement(sql_command_object)¶
创建一个
Statement
对象并返回它。该对象的execute()
方法可以稍后执行。- 参数:
sql_command_object
输入参数是一个 JSON 对象(字典),其中包含要执行的语句的文本,以及应绑定到该语句的任何值。
- 返回:
Statement
对象。- 错误:
如果出现以下情况,则会引发 JavaScript 错误:
sqlText
缺失或包含空的查询文本。语句尝试绑定数据类型不受支持的实参。有关数据类型映射的信息,请参阅 SQL 和 JavaScript 数据类型映射。有关绑定的更多信息,请参阅 绑定变量。
- 示例:
此示例不绑定任何值:
var stmt = snowflake.createStatement( {sqlText: "INSERT INTO table1 (col1) VALUES (1);"} );
此示例绑定值:
var stmt = snowflake.createStatement( { sqlText: "INSERT INTO table2 (col1, col2) VALUES (?, ?);", binds:["LiteralValue1", variable2] } );
有关绑定的更多信息(包括其他示例),请参阅 绑定变量。
- execute(command)¶
执行 SQL 命令。
- 参数:
输入与
createStatement()
方法的输入相同。- 返回:
ResultSet
对象形式的结果集。- 错误:
如果出现以下情况,则会引发 JavaScript 错误:
执行查询时发生错误,例如编译错误。
sqlText
缺失或包含空的查询文本。语句尝试绑定数据类型不受支持的实参。有关数据类型映射的信息,请参阅 SQL 和 JavaScript 数据类型映射。有关绑定的更多信息(包括其他示例),请参阅 绑定变量。
备注
此
execute()
方法(例如snowflake.execute()
)与Statement
对象中的方法(例如Statement.execute()
)不完全相同。
- log(level, message)¶
以指定的严重性级别记录消息。
- 参数:
level
记录消息的严重性级别。您可以指定以下其中一种字符串:
'off'
'trace'
'debug'
'info'
'warn'
'error'
'fatal'
message
要记录的消息。
- 错误:
如果出现以下情况,则会引发 JavaScript 错误:
level
不是字符串。level
不是上面列出的受支持的level
值之一。
- 示例:
snowflake.log("error", "Error message");
- setSpanAttribute(key, value)¶
在跟踪事件时设置当前跨度的属性。
有关使用 JavaScript 时的跟踪事件的更多信息,请参阅 使用 JavaScript 发出跟踪事件
- 参数:
key
属性的键。
value
属性的值。
- 错误:
如果出现以下情况,则会引发 JavaScript 错误:
未指定两个实参。
key
不是字符串。
- 示例:
设置一个属性,其键为
example.boolean
,其值为true
。snowflake.setSpanAttribute("example.boolean", true);
对象:Statement
¶
存储过程 Statement
对象提供一些方法,用于执行查询语句和访问有关该语句的元数据(如列数据类型)。
在创建 Statement 对象时,将会解析 SQL 并创建预处理语句。
常量¶
无。
方法¶
- execute()
此方法执行存储在此
Statement
对象中的预处理语句。- 参数:
无需参数,原因是此方法使用已存储在
Statement
对象中的信息。- 返回:
ResultSet
对象形式的结果集。- 错误:
如果查询失败,则会引发 JavaScript 错误。
- 示例:
请参阅 使用存储过程。
备注
此
execute()
方法(例如Statement.execute()
)与snowflake
对象中的方法(例如snowflake.execute()
)不完全相同。snowflake.execute(statement_in_JSON_form)
需要一个参数,即要执行的 SQL 语句。Statement.execute()
不需要参数;它使用在创建 Statement 对象时指定的 SQL 语句。
- getColumnCount()¶
此方法返回已执行查询的结果集中的列数。如果尚未执行查询,此方法会引发错误。
- 参数:
无。
- 返回:
列数。
- 错误:
如果语句尚未执行(因此不一定能够确定返回的列数),则会引发 JavaScript 错误。
- 示例:
var column_count = statement.getColumnCount();
- getColumnName(colIdx)¶
此方法返回指定列的名称。
- 参数:
列的索引号(从
1
而不是0
开始)。- 返回:
列的名称。
- 错误:
如果出现以下情况,则会引发 JavaScript 错误:
尚未执行
Statement
。不存在具有指定索引的列。
- getColumnScale(colIdx)¶
此方法返回指定列的小数位数。小数位数是指小数点后的位数。列的小数位数已在 CREATE TABLE 或 ALTER TABLE 语句中指定。例如:
create table scale_example ( n10_4 numeric(10, 4) // Precision is 10, Scale is 4. );
尽管可以针对任何数据类型调用此方法,但它原定用于数值数据类型。
- 参数:
您想获得其小数位数的列的索引(从
1
而不是0
开始)。- 返回:
列的小数位数(对于数值列);对于非数值(列)为
0
。- 错误:
如果出现以下情况,则会引发 JavaScript 错误:
尚未执行
Statement
。不存在具有指定索引的列。
- 示例:
请参阅 /developer-guide/stored-procedure/stored-procedures-usage`(搜索 :code:`getColumnScale())。
- getColumnSqlType(colIdx|colName)¶
此方法返回指定列的 SQL 数据类型。
- 参数:
列的索引号(从
1
而不是0
开始)或列的名称。(此方法会被重载以接受不同的数据类型作为参数。)列名应全部大写,除非在创建表时在列名中使用了双引号(即保留列名的大小写)。
- 返回:
列的 SQL 数据类型。
- 错误:
如果出现以下情况,则会引发 JavaScript 错误:
尚未执行
Statement
。不存在具有指定名称或索引的列。
- getColumnType(colIdx|colName)¶
此方法返回指定列的 JavaScript 数据类型。
- 参数:
列的索引号(从
1
而不是0
开始)或列的名称。(此方法会被重载以接受不同的数据类型作为参数。)列名应全部大写,除非在创建表时在列名中使用了双引号(即保留列名的大小写)。
- 返回:
列的 JavaScript 数据类型。
- 错误:
如果出现以下情况,则会引发 JavaScript 错误:
尚未执行
Statement
。不存在具有指定索引或名称的列。
- getNumDuplicateRowsUpdated()¶
此方法返回此语句更新的“重复”行(通常称为*多重联接行*)的数量。(有关如何形成多重联接行的信息,请参阅 UPDATE 语句的使用说明和示例。)
- 参数:
无。
- 返回:
数字类型的值,该值指示更新的多重联接行数。
- 错误:
如果此语句尚未执行,则会引发 JavaScript 错误。
- getNumRowsAffected()¶
此方法返回受此语句影响(例如插入/更新/删除)的行数。
如果应用了多种类型的变更(例如,MERGE 操作插入了一些行并更新了另一些行),则该数字是受所有变更影响的总行数。
- 参数:
无。
- 返回:
数字类型的值,该值指示受影响的行数。
- 错误:
如果此语句尚未执行,则会引发 JavaScript 错误。
- getNumRowsDeleted()¶
此方法返回此语句删除的行数。
- 参数:
无。
- 返回:
数字类型的值,该值指示删除的行数。
- 错误:
如果此语句尚未执行,则会引发 JavaScript 错误。
- getNumRowsInserted()¶
此方法返回此语句插入的行数。
- 参数:
无。
- 返回:
数字类型的值,该值指示插入的行数。
- 错误:
如果此语句尚未执行,则会引发 JavaScript 错误。
- getNumRowsUpdated()¶
此方法返回此语句更新的行数。
- 参数:
无。
- 返回:
数字类型的值,该值指示更新的行数。
- 错误:
如果此语句尚未执行,则会引发 JavaScript 错误。
- getRowCount()¶
此方法返回已执行查询的结果集中的行数。如果尚未执行查询,此方法会引发错误。
- 参数:
无。
- 返回:
行数。
- 错误:
如果语句尚未执行(因此无法确定返回的行数),则会引发 JavaScript 错误。
- 示例:
var row_count = statement.getRowCount();
- getQueryId()¶
此方法返回最近执行的查询的 UUID。
- 参数:
无。
- 返回:
包含 UUID 的字符串,即查询 ID。
- 错误:
如果此语句尚未执行任何查询,则此方法将引发错误“Statement is not executed yet”。
- 示例:
var queryId = statement.getQueryId();
- getSqlText()¶
此方法返回
Statement
对象中的预处理查询文本。- 参数:
无。
- 返回:
预处理查询文本的字符串。
- 错误:
无。
- 示例:
var queryText = statement.getSqlText();
- isColumnNullable(colIdx)¶
此方法返回指定的列是否允许 SQL NULL 值。
- 参数:
列的索引(从
1
而不是0
开始)。- 返回:
如果列允许 SQL NULL 值,则为
true
,否则为false
。- 错误:
如果出现以下情况,则会引发 JavaScript 错误:
尚未执行
Statement
。不存在具有指定索引的列。
- isColumnText(colIdx)¶
如果列数据类型是下列 SQL 文本数据类型之一,则此方法返回 true:
CHAR 或 CHAR(N),以及它们的同义词 CHARACTER 和 CHARACTER(N)
VARCHAR 或 VARCHAR(N)
STRING
TEXT
否则,它将返回 false。
- 参数:
列的索引(从
1
而不是0
开始)。- 返回:
如果列数据类型是 SQL 文本数据类型之一,则返回
true
;如果是所有其他数据类型,则返回false
。- 错误:
如果出现以下情况,则会引发 JavaScript 错误:
尚未执行
Statement
。不存在具有指定索引的列。
备注
此 API 提供了几种用于确定列数据类型的方法。第一种方法在上面有详细描述。其余方法具有相同的参数和错误;唯一的区别是返回值。
- isColumnArray(colIdx)¶
- 返回:
如果列数据类型是 ARRAY (对于半结构化数据),则返回
true
;如果是所有其他数据类型,则返回false
。
- isColumnBinary(colIdx)¶
- 返回:
如果列数据类型是 BINARY 或
true
,则返回 VARBINARY;如果是所有其他数据类型,则返回false
。
- isColumnBoolean(colIdx)¶
- 返回:
如果列数据类型是 BOOLEAN,则返回
true
;如果是所有其他数据类型,则返回false
。
- isColumnDate(colIdx)¶
- 返回:
如果列数据类型是 DATE,则返回
true
;如果是所有其他数据类型,则返回false
。
- isColumnNumber(colIdx)¶
- 返回:
如果列数据类型是 SQL 数值类型之一(NUMBER、NUMERIC、DECIMAL、INT、INTEGER、 BIGINT、SMALLINT、TINYINT、BYTEINT、FLOAT、FLOAT4、FLOAT8、DOUBLE、DOUBLE PRECISION 或 REAL),则返回
true
;如果是所有其他数据类型,则返回false
。
- isColumnObject(colIdx)¶
- 返回:
如果列数据类型是 OBJECT (对于半结构化数据),则返回
true
;如果是所有其他数据类型,则返回false
。
- isColumnTime(colIdx)¶
- 返回:
如果列数据类型是 TIME 或 DATETIME,则返回
true
;如果是所有其他数据类型,则返回false
。
- isColumnTimestamp(colIdx)¶
- 返回:
如果列数据类型是 SQL 时间戳类型之一(TIMESTAMP、TIMESTAMP_LTZ、TIMESTAMP_NTZ 或 TIMESTAMP_TZ),则返回
true
;如果是所有其他数据类型(包括其他日期和时间数据类型,即 DATE、TIME 或 DATETIME),则返回false
。
- isColumnVariant(colIdx)¶
- 返回:
如果列数据类型是 VARIANT (对于半结构化数据),则返回
true
;如果是所有其他数据类型,则返回false
。
对象:ResultSet
¶
此对象包含查询返回的结果。结果被视为一个含有零行或多行的集合,每行包含一列或多列。这里使用的术语“集合”并非数学意义上的集合。在数学中,集合是无序的,而 ResultSet
是有序的。
ResultSet
在某些方面类似于 SQL 游标的概念。例如,可以在 ResultSet
中一次查看一行,就像在游标中一次查看一行一样。
通常,在检索 ResultSet
后,通过重复以下操作来遍历它:
调用
next()
以获取下一行。通过调用
getColumnValue()
等方法从当前行检索数据。
如果您对 ResultSet
中的数据了解不够(例如,不知道每列的数据类型),则可以调用其他方法来获取有关数据的信息。
ResultSet
对象的某些方法与 Statement
对象的方法类似。 例如,这两个对象都具有 getColumnSqlType(colIdx)
方法。
常量¶
无。
方法¶
- getColumnCount()
此方法返回此 ResultSet 中的列数。
- 参数:
无。
- 返回:
数字类型的值,该值指示列数。
- 错误:
无。
- getColumnSqlType(colIdx|colName)
此方法返回指定列的 SQL 数据类型。
- 参数:
列的索引号(从
1
而不是0
开始)或列的名称。(此方法会被重载以接受不同的数据类型作为参数。)列名应全部大写,除非在创建表时在列名中使用了双引号(即保留列名的大小写)。
- 返回:
列的 SQL 数据类型。
- 错误:
如果出现以下情况,则会引发 JavaScript 错误:
ResultSet
为空或尚未调用next()
。不存在具有指定索引或名称的列。
- getColumnValue(colIdx|colName)¶
此方法返回当前行(即
next()
最近检索到的行)中的列值。- 参数:
列的索引号(从
1
而不是0
开始)或列的名称。(此方法会被重载以接受不同的数据类型作为参数。)列名应全部大写,除非在创建表时在列名中使用了双引号(即保留列名的大小写)。
- 返回:
指定列的值。
- 错误:
如果出现以下情况,则会引发 JavaScript 错误:
ResultSet
为空或尚未调用next()
。不存在具有指定索引或名称的列。
- 示例:
将数据库中的行转换为 JavaScript 数组:
var valueArray = []; // For each row... while (myResultSet.next()) { // Append each column of the current row... valueArray.push(myResultSet.getColumnValue('MY_COLUMN_NAME1')); valueArray.push(myResultSet.getColumnValue('MY_COLUMN_NAME2')); ... // Do something with the row of data that we retrieved. f(valueArray); // Reset the array before getting the next row. valueArray = []; }
此外,列的值可以作为
ResultSet
对象(例如myResultSet.MY_COLUMN_NAME
)的属性来访问。var valueArray = []; // For each row... while (myResultSet.next()) { // Append each column of the current row... valueArray.push(myResultSet.MY_COLUMN_NAME1); valueArray.push(myResultSet.MY_COLUMN_NAME2); ... // Do something with the row of data that we retrieved. f(valueArray); // Reset the array before getting the next row. valueArray = []; }
备注
请注意,除非在 CREATE TABLE 语句中用双引号分隔列名,否则 JavaScript 代码中的列名应全部大写。
- getColumnValueAsString(colIdx|colName)¶
此方法以字符串形式返回列的值,这在无论表中的原始数据类型如何都需要列值时非常有用。
此方法返回字符串值,这是它唯一与
getColumnValue()
方法不同的地方。有关更多详细信息,请参阅
getColumnValue()
。
- getNumRowsAffected()
此方法返回受生成了此 ResultSet 的语句影响(例如插入/更新/删除)的行数。
如果应用了多种类型的变更(例如,MERGE 操作插入了一些行并更新了另一些行),则该数字是受所有变更影响的总行数。
- 参数:
无。
- 返回:
数字类型的值,该值指示受影响的行数。
- 错误:
无。
- getQueryId()
此方法返回最近执行的查询的 UUID。
- 参数:
无。
- 返回:
包含 UUID 的字符串,即查询 ID。
- 示例:
var queryId = resultSet.getQueryId();
- getRowCount()
此方法返回此 ResultSet 中的行数。(这是总行数,而不是尚未使用的行数。)
- 参数:
无。
- 返回:
数字类型的值,该值指示行数。
- 错误:
无。
对象:SfDate
¶
JavaScript 没有与 Snowflake SQL 数据类型 TIMESTAMP_LTZ、TIMESTAMP_NTZ 和 TIMESTAMP_TZ 对应的原生数据类型。如果从数据库中检索 TIMESTAMP 类型的值,并想将其存储为 JavaScript 变量(例如,将值从 ResultSet 复制到 JavaScript 变量),请使用 Snowflake 定义的 JavaScript 数据类型 SfDate
。SfDate`(“SnowFlake 日期”)数据类型是 JavaScript 日期数据类型的扩展。:code:`SfDate
具有额外的方法,如下所述。
常量¶
无。
方法¶
除非另有说明,否则以下示例假定时区为 UTC 时区。
- getEpochSeconds()¶
此方法返回自“Unix 时间戳”(1970 年 1 月 1 日午夜)开始以来的秒数。
- 参数:
无。
- 返回:
1970 年 1 月 1 日午夜与变量中存储的时间戳之间的秒数。
- 示例:
创建存储过程:
CREATE OR REPLACE PROCEDURE test_get_epoch_seconds(TSV VARCHAR) RETURNS FLOAT LANGUAGE JAVASCRIPT AS $$ var sql_command = "SELECT '" + TSV + "'::TIMESTAMP_NTZ;"; var stmt = snowflake.createStatement( {sqlText: sql_command} ); var resultSet = stmt.execute(); resultSet.next(); var my_sfDate = resultSet.getColumnValue(1); return my_sfDate.getEpochSeconds(); $$ ;
向过程传递不同的时间戳,并检索每个时间戳自 Unix 时间戳以来的秒数。
CALL test_get_epoch_seconds('1970-01-01 00:00:00.000000000'); +------------------------+ | TEST_GET_EPOCH_SECONDS | |------------------------| | 0 | +------------------------+
CALL test_get_epoch_seconds('1970-01-01 00:00:01.987654321'); +------------------------+ | TEST_GET_EPOCH_SECONDS | |------------------------| | 1 | +------------------------+
CALL test_get_epoch_seconds('1971-01-01 00:00:00'); +------------------------+ | TEST_GET_EPOCH_SECONDS | |------------------------| | 31536000 | +------------------------+
- getNanoSeconds()¶
此方法返回对象的纳秒字段的值。请注意,这只是小数秒,而不是自 Unix 时间戳开始以来的纳秒数。因此,该值始终介于 0 和 999999999 之间。
- 参数:
无。
- 返回:
纳秒数。
- 示例:
创建存储过程:
CREATE OR REPLACE PROCEDURE test_get_nano_seconds2(TSV VARCHAR) RETURNS FLOAT LANGUAGE JAVASCRIPT AS $$ var sql_command = "SELECT '" + TSV + "'::TIMESTAMP_NTZ;"; var stmt = snowflake.createStatement( {sqlText: sql_command} ); var resultSet = stmt.execute(); resultSet.next(); var my_sfDate = resultSet.getColumnValue(1); return my_sfDate.getNanoSeconds(); $$ ; -- Should be 0 nanoseconds. -- (> SNIPPET_TAG=query_03_01 CALL test_get_nano_seconds2('1970-01-01 00:00:00.000000000');
向过程传递不同的时间戳,并从每个时间戳中检索纳秒数。
CALL test_get_nano_seconds2('1970-01-01 00:00:00.000000000'); +------------------------+ | TEST_GET_NANO_SECONDS2 | |------------------------| | 0 | +------------------------+
CALL test_get_nano_seconds2('1970-01-01 00:00:01.987654321'); +------------------------+ | TEST_GET_NANO_SECONDS2 | |------------------------| | 987654321 | +------------------------+
CALL test_get_nano_seconds2('1971-01-01 00:00:00.000123456'); +------------------------+ | TEST_GET_NANO_SECONDS2 | |------------------------| | 123456 | +------------------------+
- getScale()¶
此方法返回数据类型的精度,即小数点后的位数。例如,TIMESTAMP_NTZ(3) 的精度为 3(毫秒)。TIMESTAMP_NTZ(0) 的精度为 0(无小数秒)。TIMSTAMP_NTZ 的精度为 9(纳秒)。
最小值为 0。最大值为 9(精度为 1 纳秒)。 默认精度为 9。
- 参数:
无。
- 返回:
小数位后的位数(小数秒字段中的位数)。
- 示例:
创建存储过程:
CREATE OR REPLACE PROCEDURE test_get_scale(TSV VARCHAR, SCALE VARCHAR) RETURNS FLOAT LANGUAGE JAVASCRIPT AS $$ var sql_command = "SELECT '" + TSV + "'::TIMESTAMP_NTZ(" + SCALE + ");"; var stmt = snowflake.createStatement( {sqlText: sql_command} ); var resultSet = stmt.execute(); resultSet.next(); var my_sfDate = resultSet.getColumnValue(1); return my_sfDate.getScale(); $$ ; -- Should be 0. -- (> SNIPPET_TAG=query_04_01 CALL test_get_scale('1970-01-01 00:00:00', '0');
在此示例中,时间戳定义为 TIMESTAMP_NTZ(0),因此精度为 0。
CALL test_get_scale('1970-01-01 00:00:00', '0'); +----------------+ | TEST_GET_SCALE | |----------------| | 0 | +----------------+
在此示例中,时间戳定义为 TIMESTAMP_NTZ(2),因此精度为 2。
CALL test_get_scale('1970-01-01 00:00:01.123', '2'); +----------------+ | TEST_GET_SCALE | |----------------| | 2 | +----------------+
在此示例中,时间戳定义为 TIMESTAMP_NTZ,因此精度为 9(这是默认值)。
CALL test_get_scale('1971-01-01 00:00:00.000123456', '9'); +----------------+ | TEST_GET_SCALE | |----------------| | 9 | +----------------+
- getTimezone()¶
此方法以早于或晚于 UTC 多少分钟的形式返回时区。
- 参数:
无。
- 返回:
以早于或晚于 UTC 多少分钟来表示的时区。
- 示例:
创建存储过程:
CREATE OR REPLACE PROCEDURE test_get_Timezone(TSV VARCHAR) RETURNS FLOAT LANGUAGE JAVASCRIPT AS $$ var sql_command = "SELECT '" + TSV + "'::TIMESTAMP_TZ;"; var stmt = snowflake.createStatement( {sqlText: sql_command} ); var resultSet = stmt.execute(); resultSet.next(); var my_sfDate = resultSet.getColumnValue(1); return my_sfDate.getTimezone(); $$ ;
在此示例中,时区比 UTC 晚 8 小时(480 分钟)。
CALL test_get_timezone('1970-01-01 00:00:01-08:00'); +-------------------+ | TEST_GET_TIMEZONE | |-------------------| | -480 | +-------------------+
在此示例中,时区比 UTC 早 11 小时(660 分钟)。
CALL test_get_timezone('1971-01-01 00:00:00.000123456+11:00'); +-------------------+ | TEST_GET_TIMEZONE | |-------------------| | 660 | +-------------------+
- toString()¶
- 参数:
无。
- 返回:
此方法返回时间戳的字符串表示形式。
- 示例:
下面显示了创建
SfDate
并调用其toString
方法的简单示例:CREATE OR REPLACE PROCEDURE test_toString(TSV VARCHAR) RETURNS VARIANT LANGUAGE JAVASCRIPT AS $$ var sql_command = "SELECT '" + TSV + "'::TIMESTAMP_TZ;"; var stmt = snowflake.createStatement( {sqlText: sql_command} ); var resultSet = stmt.execute(); resultSet.next(); var my_sfDate = resultSet.getColumnValue(1); return my_sfDate.toString(); $$ ;
CALL test_toString('1970-01-02 03:04:05'); +------------------------------------------------------------------+ | TEST_TOSTRING | |------------------------------------------------------------------| | "Fri Jan 02 1970 03:04:05 GMT+0000 (Coordinated Universal Time)" | +------------------------------------------------------------------+