R0bert
R0bert

Reputation: 557

Inserting values into a table using stored procedure in snowflake

I need to insert the column names of a table into another table.

Here is my attempt:

I first created a table to insert the column names

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

When I printed out the TABLE1, I did'nt get any output. I don't understand where I'm doing wrong

Upvotes: 0

Views: 9944

Answers (1)

Darren Gardner
Darren Gardner

Reputation: 1222

When I execute your stored procedure (assume TABLE_NAME = FOO), it returns an error:

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

If you look at the SQL History, you will see that you are generating the following INSERT statement:

INSERT INTO TABLE1 VALUES(FOO,COL1);

which is missing single quotes around the literal values; it should be:

INSERT INTO TABLE1 VALUES('FOO','COL1');

To correct this, you could change this:

         var stmt2 = snowflake.createStatement({
         sqlText: "INSERT INTO TABLE1 VALUES(" + TABLE_NAME + "," + cols[i] + ")" + ";"
              });

to this:

         var stmt2 = snowflake.createStatement({
         sqlText: "INSERT INTO TABLE1 VALUES('" + TABLE_NAME + "','" + cols[i] + "')" + ";"
              });

That said, I would approach this from a different angle entirely. A more efficient way to retrieve metadata information (such as column names) is via INFORMATION_SCHEMA views. If you do NOT need to return the array of column names as output for the stored procedure, you could use something like this:

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 [];
$$
;

If you DO require that the stored procedure return the column names in an output array, then you could use something like this:

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

And there are other variations on this as well.

Upvotes: 1

Related Questions