我有一个函数来在PostgreSQL 9.5中留下垫位:
CREATE OR REPLACE FUNCTION lpad_bits(val bit varying)
RETURNS bit varying as
$BODY$
BEGIN return val::bit(32) >> (32-length(val));
END;
$BODY$
LANGUAGE plpgsql IMMUTABLE;
工作正常:
# select lpad_bits(b'1001100111000');
lpad_bits
----------------------------------
00000000000000000001001100111000
(1 row)
我的问题是当我尝试添加一个参数来改变填充量时:
CREATE OR REPLACE FUNCTION lpad_bits(val bit varying, sz integer default 1024)
RETURNS bit varying as
$BODY$
BEGIN return val::bit(sz) >> (sz-length(val));
END;
$BODY$
LANGUAGE plpgsql IMMUTABLE;
该功能现已破裂:
# select lpad_bits(b'1001100111000', 32);
ERROR: invalid input syntax for integer: "sz" LINE 1: SELECT val::bit(sz) >> (sz-length(val)) ^ QUERY: SELECT val::bit(sz) >> (sz-length(val)) CONTEXT: PL/pgSQL function lpad_bits(bit varying,integer) line 2 at RETURN
我盯着bitstring documentation和PL/pgSQL function documentation,根本没有看到这两种实现之间的根本区别。
答案 0 :(得分:1)
解析器不允许该位置的变量。另一种方法是使用常量并修剪它:
lpad
或评论中建议的import { Component,Input } from '@angular/core';
@Component({
selector: 'my-app',
template: `<h3>Angular 2 First Item in Array Missing using *ngFor</h3>
<pre>{{teachers | json}}</pre>
<teacher *ngFor="let t of teachers; let i = index" [teacherName]="t" [index]="i"></teacher>
`
})
export class AppComponent {
public teachers: string[] = [
"Erty",
"Dave",
"Sarah",
"Walter"
];
}
@Component({
selector: 'teacher',
template: `
<p>Teacher {{index}}: {{teacherName}}</p>
`
})
export class TeacherComponent {
@Input() teacherName: string;
@Input() index: number;
ngOnInit() {
console.log(this.teacherName);
}
}
功能。
答案 1 :(得分:1)
PL / pgSQL执行SQL查询,如 预处理语句 。 The manual about parameter substituion:
预备语句可以采用参数:替换的值 执行时的声明。
请注意术语 值 。只能参数化实际值,但不能使用关键字,标识符或类型名称。 32
中的bit(32)
看起来像一个值,但数据类型的修饰符在内部只是一个“值”,无法参数化。 SQL要求在规划阶段了解数据类型,它不能等待执行阶段。
您可以通过动态SQL和EXECUTE
实现目标。作为概念验证:
CREATE OR REPLACE FUNCTION lpad_bits(val varbit, sz int = 32, OUT outval varbit) AS
$func$
BEGIN
EXECUTE format('SELECT $1::bit(%s) >> $2', sz) -- literal
USING val, sz - length(val) -- values
INTO outval;
END
$func$ LANGUAGE plpgsql IMMUTABLE;
呼叫:
SELECT lpad_bits(b'1001100111000', 32);
请注意sz
用作构建语句的 literal 之间的区别,以及将其用作 value <的第二次出现的区别/ em> ,可以作为参数传递。
针对此特定任务的优秀解决方案是使用 lpad()
,例如@Abelisto suggested:
CREATE OR REPLACE FUNCTION lpad_bits2(val varbit, sz int = 32)
RETURNS varbit AS
$func$
SELECT lpad(val::text, sz, '0')::varbit;
$func$ LANGUAGE sql IMMUTABLE;
(更简单的纯SQL函数,它还允许在外部查询的上下文中使用函数内联。)
比上述功能快几倍。一个小缺陷:我们必须转向text
并返回varbit
。很遗憾,lpad()
目前尚未实施varbit
。 The manual:
以下SQL标准函数适用于位字符串以及 字符串:
length
,bit_length
,octet_length
,position
,substring
,overlay
。
overlay()
可用,我们可以提供更便宜的功能:
CREATE OR REPLACE FUNCTION lpad_bits3(val varbit, base varbit = '00000000000000000000000000000000')
RETURNS varbit AS
$func$
SELECT overlay(base PLACING val FROM bit_length(base) - bit_length(val))
$func$ LANGUAGE sql IMMUTABLE;
如果您可以使用varbit
值,则速度更快。 (如果你不得不将text
强制转换为varbit
,则优势(部分)无效。)
呼叫:
SELECT lpad_bits3(b'1001100111000', '00000000000000000000000000000000');
SELECT lpad_bits3(b'1001100111000', repeat('0', 32)::varbit);
我们可能 重叠 该变量采用整数来生成base
本身的函数:
CREATE OR REPLACE FUNCTION lpad_bits3(val varbit, sz int = 32)
RETURNS varbit AS
$func$
SELECT overlay(repeat('0', sz)::varbit PLACING val FROM sz - bit_length(val))
$func$ LANGUAGE sql IMMUTABLE;
呼叫:
SELECT lpad_bits3(b'1001100111000', 32;
相关: