#javascript #sql #stored-procedures #snowflake-cloud-data-platform
#javascript #sql #хранимые процедуры #snowflake-cloud-data-platform
Вопрос:
Мне нужно вставить имена столбцов таблицы в другую таблицу.
Вот моя попытка:
Сначала я создал таблицу для вставки имен столбцов
create or replace table TABLE1 (tab_name string, col_name string);
CREATE OR REPLACE PROCEDURE get_columns(TABLE_NAME VARCHAR)
RETURNS ARRAY
LANGUAGE JAVASCRIPT
AS
$$
var stmt = snowflake.createStatement({
sqlText: "SELECT * FROM " TABLE_NAME " LIMIT 1;",
});
stmt.execute();
var cols=[];
for (i = 1; i <= stmt.getColumnCount(); i ) {
cols.push(stmt.getColumnName(i));
}
//Values not being inserted into the table
for(i=0; i<cols.length;i )
{
var stmt2 = snowflake.createStatement({
sqlText: "INSERT INTO TABLE1 VALUES(" TABLE_NAME "," cols[i] ")" ";"
});
stmt2.execute();
}
return cols
$$;
Когда я распечатал ТАБЛИЦУ1, я не получил никаких выходных данных. Я не понимаю, где я делаю неправильно
Ответ №1:
Когда я выполняю вашу хранимую процедуру (предположим, ИМЯ_ТАБЛИЦЫ = FOO), она возвращает ошибку:
Execution error in store procedure GET_COLUMNS: SQL compilation error: error line 1 at position 26 invalid identifier 'FOO' At Statement.execute, line 18 position 15
Если вы посмотрите на историю SQL, вы увидите, что вы генерируете следующую инструкцию INSERT:
INSERT INTO TABLE1 VALUES(FOO,COL1);
в котором отсутствуют одинарные кавычки вокруг буквальных значений; это должно быть:
INSERT INTO TABLE1 VALUES('FOO','COL1');
Чтобы исправить это, вы могли бы изменить это:
var stmt2 = snowflake.createStatement({
sqlText: "INSERT INTO TABLE1 VALUES(" TABLE_NAME "," cols[i] ")" ";"
});
к этому:
var stmt2 = snowflake.createStatement({
sqlText: "INSERT INTO TABLE1 VALUES('" TABLE_NAME "','" cols[i] "')" ";"
});
Тем не менее, я бы подошел к этому с совершенно другой точки зрения. Более эффективный способ извлечения информации метаданных (например, имен столбцов) — через представления INFORMATION_SCHEMA. Если вам НЕ нужно возвращать массив имен столбцов в качестве выходных данных для хранимой процедуры, вы могли бы использовать что-то вроде этого:
CREATE OR REPLACE PROCEDURE get_columns(TABLE_NAME VARCHAR)
RETURNS ARRAY
LANGUAGE JAVASCRIPT
AS
$$
let sql_insert = `
INSERT INTO TABLE1 (
tab_name
,col_name
)
SELECT TABLE_NAME
,COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = ?
`;
snowflake.execute({"sqlText" : sql_insert, "binds" : [TABLE_NAME]});
return [];
$$
;
Если вам требуется, чтобы хранимая процедура возвращала имена столбцов в выходном массиве, тогда вы могли бы использовать что-то вроде этого:
CREATE OR REPLACE PROCEDURE get_columns(TABLE_NAME VARCHAR)
RETURNS ARRAY
LANGUAGE JAVASCRIPT
AS
$$
let sql_get_cols = `
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = ?
ORDER BY ORDINAL_POSITION
`;
let sql_insert = `
INSERT INTO TABLE1 (
tab_name
,col_name
)
VALUES (?, ?)
`;
let rs_get_cols = snowflake.execute({"sqlText" : sql_get_cols, "binds" : [TABLE_NAME]});
let cols = [];
while (rs_get_cols.next()) {
let column_name = rs_get_cols.getColumnValue(1);
snowflake.execute({"sqlText" : sql_insert, "binds" : [TABLE_NAME, column_name]});
cols.push(column_name);
}
return cols;
$$
;
И есть другие варианты этого.