ОШИБКА: отсутствует параметр $ 1 при создании представления - PullRequest
2 голосов
/ 07 апреля 2010

Когда мы пытаемся создать представление внутри функции, мы получаем ERROR: нет параметра $ 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;

Когда мы заменяем new.artikelnr в строке 7 на значение 1, оно работает так, как должно, но функция должна работать с другим артикульнором.

пример строки 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 

, он работает нормально.Извините за размещение моего вопроса очень неструктурированным.Я не очень хорошо знаю, какая информация важна для ответа на этот вопрос.

1 Ответ

0 голосов
/ 07 апреля 2010

Что это за база данных?

Что это за ключевое слово new? Этот код скопирован из какого-то триггера?

  • Заменить new на правильное имя таблицы в предложении JOIN.
  • удалить 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;

Edit:
Я мало что знаю о 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; '

Это один гигантский конкат с значением new.artikelnr, вставленным в нужных местах. Он «вставляет» буквенное значение artikelnr в код SQL, а затем вы получаете SQL, который выполняется с помощью оператора EXECUTE.

Обратите внимание, что приведенный выше код не заботится о цитировании и определенно не будет работать как есть (поскольку этот пример предназначен для образовательных целей, читатель может исправить его как упражнение:).

В документации для оператора EXECUTE вы найдете примеры, в которых используются функции цитирования, которые следует использовать для правильного построения вышеуказанной команды.

...