Вставка значений в таблицу с использованием хранимой процедуры в snowflake

#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;
  
$$
;
  

И есть другие варианты этого.