【问题标题】:ERROR: there is no parameter $1 when creating view错误:创建视图时没有参数 $1
【发布时间】:2010-04-07 14:31:08
【问题描述】:

当我们尝试在函数中创建视图时,我们得到错误:没有参数 $1。这是示例代码。

Begin

CREATE VIEW artikelnr AS
SELECT datum, 'uitgifte' as "type", CASE WHEN 'test'='test' THEN 0 END as "aantal ontvangen", aantal as "aantal uitgegeven"
FROM uitgifteregel 
JOIN artikel ON artikel.artikelnr = new.artikelnr
JOIN uitgifte ON uitgifte.uitgiftenr = uitgifteregel.uitgiftenr

UNION
SELECT datum, 'ontvangst' as "type", aantal as "aantal ontvangen" , CASE WHEN 'test'='test' THEN 0 END as "aantal uitgegeven"
FROM ontvangstregel 
JOIN artikel ON artikel.artikelnr = new.artikelnr
JOIN ontvangst ON ontvangst.ontvangstnr = ontvangstregel.ontvangstnr;
Return new; 
end;

当我们将第 7 行的 new.artikelnr 替换为值 1 时,它会正常工作,但该函数需要与不同的 artikelnr 一起使用。

示例第 7 行:JOIN artikel ON artikel.artikelnr = new.artikelnr

请为我们指明正确的方向。

回应:我们必须出于教育目的创建此视图。我上传了一张图片 我们数据库的视图和表结构:

http://img208.imageshack.us/img208/5655/tablesk.jpg

我们的第一个目标是创造 一篇文章的观点。我们通过以下代码实现了这一点:

CREATE VIEW artikelmutatiestotaal AS
SELECT null as "datum",'totaal' as "type",sum(ontvangstregel.aantal)as "aantal ontvangen",sum(uitgifteregel.aantal) as "aantal uitgegeven"
FROM uitgifteregel, ontvangstregel
UNION
SELECT datum,'uitgifte' as "type", CASE WHEN 'test'='test' THEN 0 END as "aantal ontvangen", aantal as "aantal uitgegeven"
FROM uitgifteregel 
JOIN artikel ON artikel.artikelnr = 1
JOIN uitgifte ON uitgifte.uitgiftenr = uitgifteregel.uitgiftenr
UNION
SELECT datum,'ontvangst' as "type", aantal as "aantal ontvangen" , CASE WHEN 'test'='test' THEN 0 END as "aantal uitgegeven"
FROM ontvangstregel 
JOIN artikel ON artikel.artikelnr = 1
JOIN ontvangst ON ontvangst.ontvangstnr = ontvangstregel.ontvangstnr

唯一我们无法实现的是从我们的插入语句中获取 artikelnr 的值。

CREATE FUNCTION addview() returns trigger as '
Begin
CREATE VIEW artikelnr AS
SELECT null as "datum",'totaal' as "type",sum(ontvangstregel.aantal)as "aantal ontvangen",sum(uitgifteregel.aantal) as "aantal uitgegeven"
FROM uitgifteregel, ontvangstregel
UNION
SELECT datum,'uitgifte' as "type", CASE WHEN 'test'='test' THEN 0 END as "aantal ontvangen", aantal as "aantal uitgegeven"
FROM uitgifteregel 
JOIN artikel ON artikel.artikelnr = new.artikelnr
JOIN uitgifte ON uitgifte.uitgiftenr = uitgifteregel.uitgiftenr 
UNION
SELECT datum,'ontvangst' as "type", aantal as "aantal ontvangen" , CASE WHEN 'test'='test' THEN 0 END as "aantal uitgegeven"
FROM ontvangstregel 
JOIN artikel ON artikel.artikelnr = artikelnr
JOIN ontvangst ON ontvangst.ontvangstnr = ontvangstregel.ontvangstnr
end;
'language plpgsql;

当我们替换JOIN artikel ON artikel.artikelnr = new.artikelnr 在第 7 行与

JOIN artikel ON artikel.artikelnr = 1 

它工作正常。很抱歉发布我的问题非常非结构化。我不太清楚哪些信息对于回答这个问题很重要。

【问题讨论】:

  • 为什么要创建许多不同的同名视图?那是行不通的。每个视图只是一个不同的artikelnr?你的目标是什么?您试图解决的根本问题是什么?

标签: sql postgresql join views


【解决方案1】:

这是什么数据库?

new 关键字是什么?这段代码是从某个触发器复制的吗?

  • JOIN 子句中将new 替换为正确的表名。
  • 删除Return new;

如果我没记错的话,当你拼错字段名称时,MsAccess 会报告类似的错误。
接下来是检查所有字段名称。或者,使用一些可视化查询生成器并创建这些联合查询以确保所有字段名称都是正确的。

我认为你可以放开那些 CASE 语句,只写0 AS "Some Fieldname"

试试这个。它应该工作。 (我没有针对数据库进行测试)

CREATE OR REPLACE VIEW artikelnr AS
  SELECT datum, 'uitgifte' as "type", 0 as "aantal ontvangen", 
       aantal as "aantal uitgegeven"
  FROM uitgifteregel 
  JOIN artikel ON artikel.artikelnr = uitgifteregel.artikelnr
  JOIN uitgifte ON uitgifte.uitgiftenr = uitgifteregel.uitgiftenr

UNION
  SELECT datum, 'ontvangst' as "type", aantal as "aantal ontvangen" , 
         0 as "aantal uitgegeven"
  FROM ontvangstregel 
  JOIN artikel ON artikel.artikelnr = ontvangstregel.artikelnr
  JOIN ontvangst ON ontvangst.ontvangstnr = ontvangstregel.ontvangstnr;

编辑:
我不太了解 Postgresql,但您可能应该查看 EXECUTE SCRIPT - 发送 artikelnr 作为参数,然后构造 DDL 以在脚本中查看。

根据我对其他数据库(Oracle 和 SQL 服务器)的经验,我认为您不应该为每条记录创建一个视图。你想用这种方法完成什么?

如果目标是预编译视图并提高执行速度,那么参数化查询可能也可以实现相同的目标。将其放入存储过程并发送artikelnr作为参数。

如果不是出于性能原因,请您解释一下为什么要这样做。

编辑 2:
重新回答:您不能以这种方式创建视图。问题是CREATE VIEW 接受语句而不替换值 - 它尝试使用new.artikelnr 创建视图,然后它失败,因为您在触发器之外没有表new。您需要将语句构造为字符串或文件,然后执行该语句。我检查了 PostgreSQL 的文档,有 EXECUTE 命令用于构造和执行动态命令。像这样的东西应该可以工作:

EXECUTE 
  'CREATE OR REPLACE VIEW artikelnr AS '
  || ' SELECT datum, 'uitgifte' as "type", 0 as "aantal ontvangen",' 
  || '    aantal as "aantal uitgegeven" '
  || ' FROM uitgifteregel '
  || ' JOIN artikel ON artikel.artikelnr = ' 
  || new.artikelnr
  || ' JOIN uitgifte ON uitgifte.uitgiftenr = uitgifteregel.uitgiftenr '
  || ' UNION '
  || '   SELECT datum, 'ontvangst' as "type", aantal as "aantal ontvangen" , '
  || '        0 as "aantal uitgegeven" '
  || ' FROM ontvangstregel  '
  || ' JOIN artikel ON artikel.artikelnr = '
  || new.artikelnr
  || ' JOIN ontvangst ON ontvangst.ontvangstnr = ontvangstregel.ontvangstnr; '

这是一个巨大的 concat,在正确的位置插入了 new.artikelnr 值。它将artikelnr 的文字值“插入”到SQL 代码中,然后您将获得通过EXECUTE 语句执行的SQL。

请注意,上面的代码不关心引用,它肯定不会按原样工作(因为这个例子是出于教育目的,留给读者纠正它作为练习:)。

documentation for EXECUTE statement 中,您将找到使用引用函数的示例,这些函数应该用于正确构造上述命令。

【讨论】:

  • 感谢您的快速回复。我们使用的数据库是postgresql。这段代码是一个函数,将由以下触发器执行。在每行执行程序 addview() 的 artikel 上插入后创建触发器 addview;当我们插入一个新的文章时,触发器将起作用。 artikelnr 与 productnr 的含义相同。 artikelnr 是 artikel 表的主键。 new.artikelnr 在我们的插入语句中引用了 artikelnr。我希望这可以解决一些问题。
  • 嗨。我已经编辑了帖子,因为评论留下的空间太小,无法添加信息。我希望它会有所帮助。
  • 感谢您帮助我。我将查找文档并使用执行语句。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多