有哪些选项可用于获取 Snowflake 中的主键列名称?
Posted
技术标签:
【中文标题】有哪些选项可用于获取 Snowflake 中的主键列名称?【英文标题】:What are the options available to get Primary Key Column Names in Snowflake? 【发布时间】:2021-07-15 13:41:32 【问题描述】:我需要同时获取所有主键、它们的父表名、列名和模式名。 我正在使用 INFORMATION_SCHEMA 获取所有元数据,SHOW PRIMARY KEYS/DESCRIBE TABLE 可以完成这项工作,但这里不是一个选项。
需要类似于 SELECT *FROM DB.INFORMATION_SCHEMA.XXX 的内容。 我们有哪些选择?
*我正在使用 JDBC
【问题讨论】:
How to get list of table primary keys in snowflake? 使用 JDBC 这会很困难,我们需要一个查询来获得它。 一个选项总是用存储过程包装代码并使用CALL get_pk_keys(schema/table)
?
【参考方案1】:
您可以考虑使用:getPrimaryKeys(String, String, String)
详情:https://docs.snowflake.com/en/user-guide/jdbc-api.html#object-databasemetadata
【讨论】:
听起来不错,让我试试这个,谢谢【参考方案2】:不久前,我编写了一个用户定义的表函数 (UDTF) 来获取单个表的 PK 列,PK 中的每一列作为返回中的单行。我将其扩展为返回一个包含整个数据库中 PK 中所有列的表。
创建 UDTF 后,您可以像这样获取数据库的所有 PK:
select * from table(get_pk_columns(get_ddl('database', 'MY_DB_NAME')));
它将返回一个包含模式名称、表名称和列名称列的表。请注意,如果有复合 PK,它会在表中显示为每列一行。您当然可以使用诸如 listagg() 之类的聚合函数将其更改为单行,其中复合 PK 的列名称用逗号分隔。
如果您的数据库中有大量的表/列,则 GET_DDL() 函数的返回可能会太大而无法满足 16mb 的限制。如果它确实合适,这应该会很快返回结果。
/********************************************************************************************************
* *
* User defined table function (UDTF) to get all primary keys for a database. *
* *
* @param string: DATABASE_DDL The DDL for the database to get the PKs. Usually use GET_DDL() *
* @return table: A table with the columns comprising the table's primary key *
* *
********************************************************************************************************/
create or replace function GET_PK_COLUMNS(DATABASE_DDL string)
returns table ("SCHEMA_NAME" string, "TABLE_NAME" string, PK_COLUMN string)
language javascript
as
$$
processRow: function get_params(row, rowWriter, context)
var startTableLine = -1;
var endTableLine = -1;
var dbDDL = row.DATABASE_DDL.replace(/'[\s\S]*'/gm, '')
var lines = dbDDL.split("\n");
var currentSchema = "";
var currentTable = "";
var ln = 0;
var tableDDL = "";
var pkCols = null;
var c = 0;
for (var i=0; i < lines.length; i++)
if (lines[i].match(/^create .* schema /))
currentSchema = lines[i].split("schema")[1].replace(/;/, '');
//rowWriter.writeRow(PK_COLUMN: "currentSchema = " + currentSchema);
if (lines[i].match(/^create or replace TABLE /))
startTableLine = i;
if (startTableLine != -1 && lines[i] == ");")
endTableLine = i;
if (startTableLine != -1 && endTableLine != -1)
// We found a table. Now, join it and send it for parsing
tableDDL = "";
for (ln = startTableLine; ln <= endTableLine; ln++)
if (ln > 0) tableDDL += "\n";
tableDDL += lines[ln];
startTableLine = -1;
endTableLine = -1;
currentTable = getTableName(tableDDL);
pkCols = getPKs(tableDDL);
for (c = 0; c < pkCols.length; c++)
rowWriter.writeRow(PK_COLUMN: pkCols[c], SCHEMA_NAME: currentSchema, TABLE_NAME: currentTable);
function getTableName(tableDDL)
var lines = tableDDL.split("\n");
var s = lines[1];
s = s.substring(s.indexOf(" TABLE ") + " TABLE ".length);
s = s.split(" (")[0];
return s;
function getPKs(tableDDL)
var c;
var keyword = "primary key";
var ins = -1;
var s = tableDDL.split("\n");
for (var i = 0; i < s.length; i++)
ins = s[i].indexOf(keyword);
if (ins != -1)
var colList = s[i].substring(ins + keyword.length);
colList = colList.replace("(", "");
colList = colList.replace(")", "");
var colArray = colList.split(",");
for (pkc = 0; c < colArray.length; pkc++)
colArray[pkc] = colArray[pkc].trim();
return colArray;
return []; // No PK
$$;
【讨论】:
以上是关于有哪些选项可用于获取 Snowflake 中的主键列名称?的主要内容,如果未能解决你的问题,请参考以下文章