这是本文的第三部分,描述了用于处理系统目录的用户定义函数:pg_class,pg_attribute,pg_constraints等。
本文的本节讨论返回
序列特征,继承的表以及
表属性的
特殊特征的函数。
另请参阅
记录PostgreSQL数据库的功能。 第一部分 ;
记录PostgreSQL数据库的功能。 第二部分 ;
记录PostgreSQL数据库的功能。 最后(第四部分) 。
本文的前半部分提供了有关功能实现的评论。 第二个是函数的源代码。 对于只对源文本感兴趣的读者,我们建议立即继续阅读附录 。
返回表序列特征列表的函数的结构
图 2. admtf_Table_Sequences函数所依赖的函数表11.功能用途不行 | 职称 | 预约时间 |
---|
1个 | admtf_Sequence_Features | 该函数返回表序列特征的列表。 |
2 | admtf_Table_Sequences | 该函数返回数据库表序列及其特征的列表。 |
Admtf_Sequence_Features函数-数据库序列特征列表
admtf_Sequence_Features函数返回数据库SEQUENCE特征的列表。 可以在此处查看和下载源代码 。
admtf_Sequence_Features函数返回数据库序列特征的列表( SEQUENCE )
。
作为参数,该函数采用序列的名称( a_SequenceName )和在其中创建序列的方案的名称( a_SchemaName )。
之所以需要admtf_Sequence_Features函数,是因为该序列的主要特征实际上存储在名称与序列名称匹配的表中,并且使用SELECT语句从中提取数据。 在这种情况下,序列的名称,方案的名称以及对该序列的注释存储在pg_class , pg_namespace和pg_description目录中 。
SELECT * FROM kr_road_network_vertices_pgr_id_seq;
备注6
PostgreSQL 10分离了序列的特征及其状态的特征。 为此, 引入了具有序列特征的pg_sequence目录,其中包含序列的初始值( start_value ),增量( crement_by )和最大值( max_value )。 序列返回的最后一个值( last_value )保留在“表”中,并带有序列的名称。
备注的结尾。
我认为,将每个序列表示为表的类似物是由需要存储序列的最后使用值( last_value )决定的,该值是序列状态的特征,而不是序列本身。
pg_class目录中的序列条目与表条目的区别在于关系类型的值(relkind = 'S' )。
为了提取任意序列的特征,您必须使用动态SQL。
EXECUTE 'SELECT last_value,start_value,increment_by,max_value FROM '|| LOWER(a_SchemaName)||'.'||LOWER(a_SequenceName) INTO v_SequenceLastValue,v_SequenceStartValue, v_SequenceIncrementBy,v_SequenceMaxValue ;
表12.执行admtf_Sequence_Features函数(“ public”,“ kr_road_network_vertices_pgr_id_seq”)的结果。职称 | 评注 | 现时 | 开始 | 增量式 | 结束 |
---|
kr_road_network _vertices_pgr_id _seq | 顺序 | 138023 | 1个 | 1个 | 9223372036854775807 |
数据库表序列及其特征的功能admtf_Table_Sequences列表
admtf_Table_Sequences函数返回数据库表的序列列表( SEQUENCE ),生成其字段值和这些序列的特征。 可以在此处查看和下载源代码 , 这是不使用游标的函数的版本 。
作为参数,该函数采用源表的名称( a_TableName )和在其中创建表的方案的名称(
a_SchemaName
)

图中操作员的源代码 SELECT pseq.relname AS SequenceName,snsp.nspname AS SequenceSchemaName, COALESCE(dsc.description,', ' ||da.attname) AS SequenceDescription, d.depType AS DependcyType,da.attname AS AttributeName FROM pg_depend d INNER JOIN pg_class pseq ON d.objid = pseq.oid INNER JOIN pg_namespace snsp ON pseq.relnamespace=snsp.oid LEFT OUTER JOIN pg_Description dsc ON pseq.oid=dsc.objoid AND dsc.objsubid=0 INNER JOIN pg_class tbl ON d.refobjid = tbl.oid INNER JOIN pg_namespace nsp ON tbl.relnamespace=nsp.oid INNER JOIN pg_attribute da ON da.attrelid= d.refobjid AND da.attnum= d.refobjsubid WHERE LOWER(nsp.nspname)=LOWER(a_SchemaName) AND LOWER(tbl.relname)=LOWER(a_TableOID) AND tbl.relkind = 'r' AND pseq.relkind = 'S' ORDER BY pseq.relname;
单个序列的描述是pg_class中的记录的组合,该记录将其描述为物理关系,条件表的序列名称包含有关序列特定特征的数据
有关序列和源表之间关系的信息存储在pg_depend系统目录中。
表13.实现该功能所需的pg_depend目录的属性。职称 | 内容描述 |
---|
对象 | pg_class目录中序列的OID |
objsubid | 该字段包含零 |
refobjid | 使用顺序字段的表的OID |
refobjsubid | 表属性号,其值使用序列填充 |
另外,该函数访问目录数据pg_namespace和pg_description以便提取序列和源表的图表和注释。
为了确定表的属性,该表的值使用序列填充,该函数在以下条件下访问pg_attribute目录: attrelid = refobjid和attnum = refobjsubid 。 (在这种情况下, pg_depend目录属性的名称显示在等号的右侧)。
通过调用admtf_Sequence_Features在循环中检索表序列的特殊特征。 之所以使用循环,是因为可以分配多个序列来填写表格的字段。
表14.执行admtf_Table_Sequences函数(“ public”,“ kr_road_network_vertices_pgr”)的结果。职称 | 评注 | 开始 | 增量式 | 结束 | 领域 |
---|
kr_road_network _vertices_pgr_id _seq | 序列生成ID字段值 | 1个 | 1个 | 9223372036854775807 | 编号 |
没有光标的版本
在版本低于10的PostgreSQL环境中,最有可能在不使用游标的情况下实现admtf_Table_Sequences函数。
但是版本10的幸运所有者可以很好地使用游标,因为 他们可以使用pg_sequence目录。 在这种情况下,可以使用单个SELECT语句检索序列的所有特征。
在给定的函数实现中,使用窗口函数RANK()OVER(PARTITION BY pseq.relname) ,计算用于填充源表的序列的序列号。

图中操作员的源代码 SELECT RANK() OVER (PARTITION BY pseq.relname) AS SequenceNo, pseq.relname AS SequenceName,snsp.nspname AS SequenceSchemaName, COALESCE(dsc.description,', ' ||da.attname) AS SequenceDescription, seq.seqstart AS SequenceStartValue,seq.seqincrement AS SequenceIncrementBy, seq.seqmax AS SequenceMaxValue, d.depType AS DependcyType,da.attname AS AttributeName FROM pg_depend d INNER JOIN pg_class pseq ON d.objid = pseq.oid INNER JOIN pg_sequence seq ON seq.seqrelid= pseq.oid INNER JOIN pg_namespace snsp ON pseq.relnamespace=snsp.oid LEFT OUTER JOIN pg_Description dsc ON pseq.oid=dsc.objoid AND dsc.objsubid=0 INNER JOIN pg_class tbl ON d.refobjid = tbl.oid INNER JOIN pg_namespace nsp ON tbl.relnamespace=nsp.oid INNER JOIN pg_attribute da ON da.attrelid= d.refobjid AND da.attnum= d.refobjsubid WHERE LOWER(nsp.nspname)=LOWER(a_SchemaName) AND LOWER(tbl.relname)=LOWER(a_TableOID) AND tbl.relkind = 'r' AND pseq.relkind = 'S' ORDER BY pseq.relname;
备注7
。
此版本的函数不返回序列( last_value )生成的最后一个值。
备注的结尾。
Admtf_Table_InheritanceChildrens函数-继承表的特征列表
admtf_Table_InheritanceChildrens函数返回数据库表的继承表( INHERITS )的特征列表。 可以在此处查看和下载源代码 。
该函数将源表的名称( a_TableName )和在其中创建表的方案的名称( a_SchemaName )作为参数。
单个旧表的描述在pg_class的条目中。 但是要按源表的名称搜索继承的表,必须使用pg_depend系统目录。
表15.实现该功能所需的pg_depend目录的属性。职称 | 内容描述 |
---|
对象 | pg_class目录中继承表的OID |
refobjid | 源表的OID |

图中操作员的源代码 SELECT rtbl.relname,rnspc.nspname,rdsc.description,rtbl.relnatts::INTEGER, rtbl.relchecks::INTEGER, rtbl.relhaspkey,rtbl.relhasindex,rtbl.relhassubclass, rtbl.reltuples::INTEGER FROM pg_class tbl INNER JOIN pg_namespace nspc ON tbl.relnamespace = nspc.oid LEFT OUTER JOIN pg_Description dsc ON tbl.oid=dsc.objoid AND dsc.objsubid=0 INNER JOIN pg_depend dp ON tbl.oid=dp.refobjid INNER JOIN pg_class rtbl ON rtbl.OID=dp.objid INNER JOIN pg_namespace rnspc ON rtbl.relnamespace = rnspc.oid LEFT OUTER JOIN pg_Description rdsc ON rtbl.oid=rdsc.objoid AND rdsc.objsubid=0 WHERE LOWER(nspc.nspname)=LOWER(a_SchemaName) AND LOWER(tbl.relname)=LOWER(a_TableOID) AND tbl.relkind = 'r' AND rtbl.relkind = 'r' ORDER BY rtbl.relname;
另外,该函数访问目录数据pg_namespace和pg_description以便为继承表和源表提取模式和注释。
表16.执行函数admtf_Table_InheritanceChildrens(“ public”,“ np_house”)的结果。职称 | 评注 | 属性 | ? 主键 | ? 指标 | ? 后裔 | 记录数 |
---|
np_house 04201 000000 | 定居点的房屋(阿钦斯基区) | 15 | ˚F | ˚F | ˚F | 5651 |
np_house 4208 000 000 | 定居点的房屋(波哥大斯基区) | 15 | ˚F | ˚F | ˚F | 4314 |
从pg_class目录的reltuple属性中选择生成的表中的记录数。 尽管此值通常与表中的实际条目数完全匹配,但它仍然是估计值。 因此,您可能想要获得确切的结果。 例如,如图所示。
EXECUTE 'SELECT COUNT(*) FROM '||LOWER(a_SchemaName)||'.'||LOWER(a_TableName) INTO v_TableNumberOfRowCalc;
但是,首先,为了在文本中实现该语句,函数admtf_Table_InheritanceChildrens将必须使用游标。
其次,我希望该功能同时显示表条目的估计数量和确切数量。
因此,该函数具有另一个可选参数-获取表条目数的模式( a_Mode ),该模式采用值“ estimate”( 估计 )或“ exactly”( 精确 )。
此外,还创建了admfn_Table_RowCount函数,该函数返回表条目的准确数量,并且reltuple属性在SELECT返回列表中被替换为以下结构。

图中操作员的源代码 CASE WHEN a_Mode = 'exactly' THEN admfn_Table_RowCount(rnspc.nspname,rtbl.relname) ELSE reltuples END
结果,如果参数a_Mode没有指定返回精确值的要求,则该函数返回指标“表条目数”的估计值。
返回表属性特征列表的函数的结构
图 3. admtf_Attribute_Features调用的函数
图中表格的文本版本表17.功能目的。不行 | 职称 | 预约时间 |
---|
1个 | admtf_Attribute_PKFeatures | 该函数返回主键(PRIMARY KEY)中的属性存在属性,以及该键的一部分特性。 |
2 | admtf_Attribute_FKFeatures | 该函数返回外键(FOREIGN KEY)中的属性存在属性,以及该键的一部分特性。 |
3 | admtf_Attribute_Features | 该函数返回表属性特征的列表。 |
函数admtf_Attribute_PKFeatures--属性是否存在于主键中
admtf_Attribute_PKFeatures函数返回表的主键(PRIMARY KEY)中是否存在表属性的符号,如果存在,则该键中的序列号是多少,因为 主键可以是复合键。
可以在此处查看和下载源代码 。
该函数将源表的OID( a_TableOID )和其中所需属性的序列号( a_AttributeNo )作为参数。
该函数从pg_constraint目录条目中提取所需的数据,其中包含源表的(CONSTRAINT)约束,包括主键约束。 所需表的OID存储在conrelid字段中,主键描述存储在一条记录中,其中contype字段包含值``p'
。
SELECT INTO v_PKAttributeList,rs_isAttributePK conkey,ARRAY[a_AttributeNo]<@conkey FROM pg_constraint c WHERE c.contype='p' AND c.conrelid=a_TableOID;
以这种方式找到的conkey字段包含组成主键的属性编号数组。 因此,为了检查主键中source属性的存在,足以计算逻辑表达式ARRAY [a_AttributeNo] <@ conkey 。
如果主键中存在该属性,则在循环中计算其序列号。
函数admtf_Attribute_FKFeatures-外键中是否存在该属性
admtf_Attribute_FKFeatures函数返回表的一个或多个外键(FOREIGN KEY)中是否存在表属性的符号,如果存在,则在这些键中其序号是什么,因为 外键可以是复合键。
可以在此处查看和下载源代码 。
该函数将源表的OID( a_TableOID )和其中所需属性的序列号( a_AttributeNo )作为参数。
该函数从包含源表CONSTRAINT的pg_constraint目录条目中检索所需的数据,包括但不限于外键约束。 所需表的OID存储在conrelid字段中,主键描述存储在一条记录中,其中contype字段包含值“ f”
。
SELECT * FROM pg_constraint c WHERE c.contype='f ' AND c.conrelid=a_TableOID AND ARRAY[a_AttributeNo]<@conkey ORDER BY c.oid;
以这种方式找到的conkey字段包含组成外键的属性号数组。 因此,为了检查外键中源属性的存在,只需计算逻辑表达式ARRAY [a_AttributeNo] <@ conkey即可 。
如果该属性存在于外键中,则在循环中,在包含该属性的外键中形成其序列号的数组。 此外,表名称及其属性构成了另外两个数组,这些数组由source属性在包含该表的外键中引用。
通过从外键项的confrelid字段中检索的标识符(OID)从pg_class目录项中检索表名。
要获取外部表的属性名称,请使用字段中的序列号数组
key
(其名称与上面的数组不同,字母为“
f ”)。 从该数组中提取与外部属性对应的外部表的属性的序列号。 通过外部表的属性的此序列号及其OID(位于pg_attribute目录中),可以找到用于描述属性的条目,并检索其名称。
Admtf_Attribute_Features函数-表属性特征列表
admtf_Attribute_Features函数返回以下表属性特征的列表。 可以在此处查看和下载源代码 。

图中表格的文本版本不行 | 职称 | 型式 | 预约时间 |
---|
1个 | AttributeName | 名 | 源属性的名称。 |
2 | UserTypeName | VARCHAR(256) | 自定义来源属性类型 |
3 | 类型名 | VARCHAR(256) | 源属性的基本类型 |
4 | isNotNULL | 布兰 | ? 空有效性 |
5 | isAttributePK | 布兰 | ? 参与PK |
6 | 列PKNo | 小灵通 | PK中的属性序列号 |
7 | 内容描述 | 文字 | 评论来源属性 |
8 | isAttributeFK | 布兰 | ? 参加FK |
9 | FKeyName | 名字[] | 约束表名称的数组,其中定义了外键 |
10 | 列号 | SMALLINT [] | 表的外键中的属性序列号数组 |
11 | FKTableName | 名字[] | 外键引用的表的数组 |
12 | FKTableColumnName | 名字[] | 外部表中与源属性相对应的属性名称数组 |
该函数将源表的OID( a_TableOID )和其中所需属性的序列号( a_AttributeNo )作为参数。
从与输入参数的值相对应的pg_attribute目录条目中检索AttributeName和isNotNULL字段的值。
SELECT attr.attname, attr.attnotnull FROM pg_attribute attr WHERE attr.attrelid =a_TableOID AND attr.attnum=a_AttributeNo; SELECT rs_isAttributePK,rs_ColumnPKNo FROM admtf_Attribute_PKFeatures (a_TableOID,a_AttributeNo); SELECT rs_isAttributeFK,rs_FKeyName,rs_ColumnFKNo, rs_FKTableName,rs_FKTableColumnName FROM admtf_Attribute_FKFeatures (a_TableOID,a_AttributeNo);
admtf_Attribute_PKFeatures函数返回isAttributePK和ColumnPKNo字段的值。
isAttributeFK , FKeyName , ColumnFKNo , FKTableName , FKTableColumnName字段的值由admtf_Attribute_FKFeatures函数返回。
调用admtf_Attribute_Features((从pg_class中的SELECT OID,其中relname ='street'),2 :: SMALLINT)将产生以下结果。
表18.执行函数admtf_Attribute_Features的结果AttributeName | UserTypeName | 类型名 | isNotNULL | isAttributePK | 列PKNo |
---|
地区性 | 地区性 | 整数 | 整数 | 整数 | 整数 |
内容描述 | isAttributeFK | FKeyName | 列号 | FKTableName | FKTableColumnName |
---|
社区ID | Ť | {fk_street_locality} | {2} | {locality} | {localityid} |
附录1.脚本
创建admtf_Sequence_Features函数
有关功能源代码的注释,请参见此处。功能码 BEGIN TRANSACTION; DROP FUNCTION IF EXISTS admtf_Sequence_Features (a_SchemaName NAME,a_SequenceName NAME); CREATE OR REPLACE FUNCTION admtf_Sequence_Features (a_SchemaName NAME default 'public', a_SequenceName NAME default NULL ) RETURNS TABLE (rs_SequenceName NAME,rs_SequenceDescription TEXT,rs_NumberOfAttribute INTEGER,rs_SequenceLastValue BIGINT, rs_SequenceStartValue BIGINT,rs_SequenceIncrementBy BIGINT,rs_SequenceMaxValue BIGINT) AS $BODY$ DECLARE c_SequenceKind CONSTANT CHAR:='S'; v_SequenceOID OID; v_SequenceName NAME; v_SequenceDescription TEXT; v_SequenceStartValue BIGINT; v_SequenceIncrementBy BIGINT; v_SequenceMaxValue BIGINT; v_SequenceLastValue BIGINT; v_SequenceNumberOfRowCalc INTEGER;
创建admtf_Table_Sequences函数
有关功能源代码的注释,请参见此处。功能码 BEGIN TRANSACTION; DROP FUNCTION IF EXISTS admtf_Table_Sequences (a_SchemaName NAME, a_TableName NAME); CREATE OR REPLACE FUNCTION admtf_Table_Sequences (a_SchemaName NAME default 'public', a_TableName NAME default NULL ) RETURNS TABLE (r_SequenceNumber SMALLINT,r_SequenceName NAME, r_SequenceSchemaName NAME,r_SequenceDescription TEXT, r_SequenceStartValue BIGINT,r_SequenceIncrementBy BIGINT, r_SequenceMaxValue BIGINT,r_DependType NAME, r_RefTableName NAME,r_RefTableSchemaName NAME, r_RefAttributeName NAME) AS $BODY$ DECLARE v_TableOID INTEGER; v_Sequence RECORD; v_SequenceOID INTEGER; v_SequenceName NAME; v_SequenceSchemaName NAME; v_SequenceDescription TEXT; v_SequenceStartValue BIGINT; v_SequenceIncrementBy BIGINT; v_SequenceMaxValue BIGINT; v_DependcyType NAME; v_AttributeName NAME; v_SequenceNumber SMALLINT; c_Delimiter CONSTANT VARCHAR(2):=',';
admtf_Table_Sequences (PostgreSQL 10)
. BEGIN TRANSACTION; DROP FUNCTION IF EXISTS admtf_Table_Sequences (a_SchemaName NAME, a_TableName NAME); CREATE OR REPLACE FUNCTION admtf_Table_Sequences (a_SchemaName NAME default 'public', a_TableName NAME default NULL ) RETURNS TABLE (r_SequenceNumber SMALLINT,r_SequenceName NAME, r_SequenceSchemaName NAME,r_SequenceDescription TEXT, r_SequenceStartValue BIGINT,r_SequenceIncrementBy BIGINT, r_SequenceMaxValue BIGINT,r_DependType NAME, r_RefTableName NAME,r_RefTableSchemaName NAME, r_RefAttributeName NAME) AS $BODY$ DECLARE v_TableOID INTEGER; v_Sequence RECORD; v_SequenceOID INTEGER; v_SequenceName NAME; v_SequenceSchemaName NAME; v_SequenceDescription TEXT; v_SequenceStartValue BIGINT; v_SequenceIncrementBy BIGINT; v_SequenceMaxValue BIGINT; v_DependcyType NAME; v_AttributeName NAME; v_SequenceNumber SMALLINT; c_Delimiter CONSTANT VARCHAR(2):=',';
admfn_Table_RowCount
. BEGIN TRANSACTION; DROP FUNCTION IF EXISTS admfn_Table_RowCount (a_SchemaName NAME,a_TableName NAME); CREATE OR REPLACE FUNCTION admfn_Table_RowCount (a_SchemaName NAME default 'public', a_TableName NAME default NULL ) RETURNS BIGINT AS $BODY$ DECLARE v_TableNumberOfRowCalc BIGINT; v_Found BOOLEAN;
admtf_Table_InheritanceChildrens
. BEGIN TRANSACTION; DROP FUNCTION IF EXISTS admtf_Table_InheritanceChildrens (a_SchemaName NAME,a_TableName NAME,a_Mode VARCHAR(10)); CREATE OR REPLACE FUNCTION admtf_Table_InheritanceChildrens (a_SchemaName NAME default 'public', a_TableName NAME default NULL, a_Mode VARCHAR(10) default 'estimate' ) RETURNS TABLE (rs_TableName NAME,rs_TableDescription TEXT, rs_NumberOfAttribute INTEGER,rs_NumberOfChecks INTEGER, rs_hasPKey BOOLEAN,rs_hasIndex BOOLEAN, rs_hasSubClass BOOLEAN,rs_NumberOfRow INTEGER) AS $BODY$ DECLARE c_TableKind CONSTANT CHAR:='r'; c_ExactlyMode CONSTANT VARCHAR(10):='exactly'; c_EstimateMode CONSTANT VARCHAR(10):='estimate'; v_TableOID OID; v_SchemaName NAME; v_TableName NAME; v_TableDescription TEXT; v_TableNumberOfRowCalc INTEGER; v_InheritanceRECORD RECORD; v_InheritanceOID OID; BEGIN RETURN QUERY SELECT rtbl.relname,rdsc.description,rtbl.relnatts::INTEGER, rtbl.relchecks::INTEGER,rtbl.relhaspkey,rtbl.relhasindex, rtbl.relhassubclass, CASE WHEN a_Mode=c_ExactlyMode THEN admfn_Table_RowCount(rnspc.nspname,rtbl.relname)::INTEGER ELSE rtbl.reltuples::INTEGER END FROM pg_class tbl INNER JOIN pg_namespace nspc ON tbl.relnamespace = nspc.oid LEFT OUTER JOIN pg_Description dsc ON tbl.oid=dsc.objoid AND dsc.objsubid=0 INNER JOIN pg_depend dp ON tbl.oid=dp.refobjid INNER JOIN pg_class rtbl ON rtbl.OID=dp.objid INNER JOIN pg_namespace rnspc ON rtbl.relnamespace = rnspc.oid LEFT OUTER JOIN pg_Description rdsc ON rtbl.oid=rdsc.objoid AND rdsc.objsubid=0 WHERE nspc.nspname=LOWER(a_SchemaName) AND tbl.relkind=c_TableKind AND rtbl.relkind=c_TableKind AND tbl.relname =LOWER(a_TableName) ORDER BY rtbl.relname; END $BODY$ LANGUAGE plpgsql; COMMENT ON FUNCTION admtf_Table_InheritanceChildrens(a_SchemaName NAME,a_TableName NAME,a_Mode VARCHAR(10)) IS ' ';
admtf_Attribute_PKFeatures
. BEGIN TRANSACTION; DROP FUNCTION IF EXISTS admtf_Attribute_PKFeatures (a_TableOID OID,a_AttributeNo SMALLINT); CREATE OR REPLACE FUNCTION admtf_Attribute_PKFeatures (a_TableOID OID, a_AttributeNo SMALLINT ) RETURNS TABLE (rs_isAttributePK BOOLEAN,rs_PKeyName name,rs_ColumnPKNo SMALLINT) AS $BODY$ DECLARE C_PKAttributeList_NDims CONSTANT INTEGER:=1; v_PKAttributeList SMALLINT[]; v_PKAttributeIndx INTEGER; v_PKAttributeLBound INTEGER; v_PKAttributeUBound INTEGER;
admtf_Attribute_FKFeatures
. BEGIN TRANSACTION; DROP FUNCTION IF EXISTS admtf_Attribute_FKFeatures (a_TableOID OID,a_AttributeNo SMALLINT); CREATE OR REPLACE FUNCTION admtf_Attribute_FKFeatures (a_TableOID OID, a_AttributeNo SMALLINT ) RETURNS TABLE (rs_isAttributeFK BOOLEAN,rs_FKeyName name[],rs_ColumnFKNo SMALLINT[],rs_FKTableName name[],rs_FKTableColumnName name[]) AS $BODY$ DECLARE C_FKAttributeList_NDims CONSTANT INTEGER:=1; v_FKAttributeList SMALLINT[]; v_RefAttributeList SMALLINT[]; v_FKAttributeIndx INTEGER; v_RefAttributeListIndx INTEGER; v_FKAttributeLBound INTEGER; v_FKAttributeUBound INTEGER; v_FKConstraintIndx INTEGER; v_FKeyName name; v_FKTableName name; v_FKTableColumnName name; v_RefAttributeNo SMALLINT; v_Constraint pg_constraint%ROWTYPE;
admtf_Attribute_Features
. BEGIN TRANSACTION; DROP FUNCTION IF EXISTS admtf_Attribute_Features (a_TableOID OID,a_AttributeNo SMALLINT); CREATE OR REPLACE FUNCTION admtf_Attribute_Features (a_TableOID OID, a_AttributeNo SMALLINT ) RETURNS TABLE (rsa_AttributeName name,rsa_UserTypeName VARCHAR(256),rsa_TypeName VARCHAR(256),rsa_isNotNULL BOOLEAN,rsa_isAttributePK BOOLEAN, rsa_ColumnPKNo SMALLINT,rsa_Description Text,rsa_isAttributeFK BOOLEAN,rsa_FKeyName name[],rsa_ColumnFKNo SMALLINT[],rsa_FKTableName name[],rsa_FKTableColumnName name[]) AS $BODY$ DECLARE v_Return_Error Integer := 0;
另请参阅
PostgreSQL. ;PostgreSQL. .PostgreSQL. ( ) .