Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2003.09.01;
Скачать: [xml.tar.bz2];

Вниз

Хран. проц.: обратится к столбцу таблицы по зад. в парам. имени?   Найти похожие ветки 

 
paxer   (2003-08-06 14:50) [0]

Вот собираюсь написать свою первую хранимую процедуру. И встала такая проблемка: можно ли в хран. процедуре обращаться к столбцу таблицы по заданному в параметре имени? Если можно, то хотел бы коротенький пример увидеть. А то в книгах ответ на данный вопрос не встречал.
Д5, Интербейз.


 
Жук   (2003-08-06 15:17) [1]

А зачем ?


 
HSolo   (2003-08-06 15:19) [2]

Нет


 
paxer   (2003-08-06 15:29) [3]

Есть большое число справочников иерархической структуры. Надо получить все элементы, принадлежащие указанной группе. Столбцы называются так:
sНомерСправочникаId, sНомерСправочникаParentId.
Хочется написать одну процедуру, работающую для всех справочников а не создавать для каждого отдельную.


 
paxer   (2003-08-06 15:31) [4]

>HSolo
А жаль...
Спасибо.


 
Жук   (2003-08-06 15:34) [5]

Непонятно всё равно, зачем нужно имена столбцов передавать параметрически.


 
paxer   (2003-08-06 15:45) [6]

Хорошо. Задам вопрос по другому. Как одной хранимой процедурой возвращать список номеров элеменов принадлежащих заданной группе для любого справочника описанной выше структуры? Справочники имеют вид:

1: s1Id, s1ParentId
2: s2Id, s2ParentId
и т.д.

По большому счету мне достаточно примера процедуры, возвращающей к примеру, список всех Id в заданном справочнике.


 
Жук   (2003-08-06 16:02) [7]

Понял. Тут действительно никак. Нужно было (раз уж у справочников одинаковая структура) их в одну таблицу совать. Теперь уж ничего не попишешь.


 
paxer   (2003-08-06 16:05) [8]

Структура то у справочников разная, просто все они содержат Id и ParentId. Вот и хотелось красиво извернуться.


 
HSolo   (2003-08-06 16:12) [9]

Иначе говоря, нужен список всех потомков указанной записи?
Вот пример (написано с ходу)

CREATE TABLE KS_DEPARTMENT (
FID_KS_DEPARTMENT INTEGER NOT NULL,
FID_PARENT_KS_DEPARTMENT INTEGER,
FNAME VARCHAR(100));

ALTER TABLE KS_DEPARTMENT ADD CONSTRAINT PK_KS_DEPARTMENT PRIMARY KEY (FID_KS_DEPARTMENT);

ALTER TABLE KS_DEPARTMENT ADD CONSTRAINT FK_KS_DEPARTMENT_PARENT FOREIGN KEY (FID_PARENT_KS_DEPARTMENT) REFERENCES KS_DEPARTMENT (FID_KS_DEPARTMENT) ON UPDATE CASCADE;


Процедура выборки всех потомков указанной записи:
CREATE PROCEDURE GET_DEPARTMENT_WITH_CHILDREN(
MYID INTEGER)
RETURNS (
FID INTEGER,
FNAME VARCHAR(100),
FID_PARENT INTEGER)
AS
begin
for select fid_ks_department, fname, fid_parent_ks_department
from ks_department
where fid_parent_ks_department = :myid
into :fid, :fname, :fid_parent
do begin
suspend;
for select fid, fname, fid_parent
( :fid) Иначе говоря, нужен список всех потомков указанной записи?
Вот пример (написано с ходу)

CREATE TABLE KS_DEPARTMENT (
FID_KS_DEPARTMENT INTEGER NOT NULL,
FID_PARENT_KS_DEPARTMENT INTEGER,
FNAME VARCHAR(100));

ALTER TABLE KS_DEPARTMENT ADD CONSTRAINT PK_KS_DEPARTMENT PRIMARY KEY (FID_KS_DEPARTMENT);

ALTER TABLE KS_DEPARTMENT ADD CONSTRAINT FK_KS_DEPARTMENT_PARENT FOREIGN KEY (FID_PARENT_KS_DEPARTMENT) REFERENCES KS_DEPARTMENT (FID_KS_DEPARTMENT) ON UPDATE CASCADE;


Процедура выборки всех потомков указанной записи:
CREATE PROCEDURE GET_DEPARTMENT_WITH_CHILDREN(
MYID INTEGER)
RETURNS (
FID INTEGER,
FNAME VARCHAR(100),
FID_PARENT INTEGER)
AS
begin
for select fid_ks_department, fname, fid_parent_ks_department
from ks_department
where fid_parent_ks_department = :myid
into :fid, :fname, :fid_parent
do begin
suspend;
for select fid, fname, fid_parent
from get_department_with_children(:fid)
into :fid, :fname, :fid_parent
do suspend;
end
end

Саму указанную запись не вернет; если надо - подкрутите.
Оно?


 
paxer   (2003-08-06 16:37) [10]

То что я хотел, должно по идее выглядеть так:
(не судите новичка строго)
Пример упрощенный, т.к. по идее надо использовать рекурсию.

CREATE PROCEDURE GET_DEPARTMENT_WITH_CHILDREN(
MYID INTEGER
IdName VARCHAR(20)
IdParentName VARCHAR(20)
TableName VARCHAR(20))
RETURNS (
FID INTEGER,
FNAME VARCHAR(100),
FID_PARENT INTEGER)
AS
begin
for select :IdName, :IdParentName
from :TableName
where :IdName = :myid
into :fid, :fname, :fid_parent
do suspend;
end


 
HSolo   (2003-08-06 16:49) [11]

Не совсем понимаю. Вот пример таблицы:

FID FID_PARENT
1 null
2 1
3 1
4 2
5 2
6 3
7 3
8 6
9 ( 06.08.03 16:12) Не совсем понимаю. Вот пример таблицы:

FID FID_PARENT
1 null
2 1
3 1
4 2
5 2
6 3
7 3
8 6
9 6

Что Вы желаете получить?

1) Список всех потомков некой записи - т.е. напр. для записи с fid=2 это 4 и 5, для записи с fid=3 - 6, 7, 8, 9. Если Вам нужно именно это - то см. HSolo © (06.08.03 16:12)

2) Список всех записей в таблице - тогда либо Вам не нужна рекурсия, выбирайте все как есть, либо подайте на вход процедуре ID_PARENT корневой записи, если это null - то подкрутите процедуру, добавив проверку на null


 
paxer   (2003-08-06 17:48) [12]

Упростим задачу, акцентируя внимание на том, что не получается.
Есть три таблицы:

s1:
s1Id s1v
1 "1"
1 "2"
2 "3"

s2:
s2Id s2v
1 "4"
3 "2"
2 "3"

s3:
s3Id s3v
5 "6"
1 "4"
2 ( для s1 - "1","2",для s2 - "4", для s3 - "4") Упростим задачу, акцентируя внимание на том, что не получается.
Есть три таблицы:

s1:
s1Id s1v
1 "1"
1 "2"
2 "3"

s2:
s2Id s2v
1 "4"
3 "2"
2 "3"

s3:
s3Id s3v
5 "6"
1 "4"
2 "3"

Нужно написать хранимую процедуру, которая вернет все sXv для указанного значения Id для выбранной процедуры(для s1 - "1","2",для s2 - "4", для s3 - "4").
Соответственно, данная процедура должна работать с любой из указанных таблиц. Т.е. имя таблицы, с которой работает процедура должно ей передаваться параметрически, и, соответственно названия столбцов тоже должны перадаваться в качестве параметров.


 
HSolo   (2003-08-06 18:00) [13]

> Нужно написать хранимую процедуру, которая вернет все sXv для указанного значения Id для выбранной процедуры(для s1 - "1","2",для s2 - "4", для s3 - "4").

См. HSolo © (06.08.03 16:12)

> Соответственно, данная процедура должна работать с любой из указанных таблиц. Т.е. имя таблицы, с которой работает процедура должно ей передаваться параметрически, и, соответственно названия столбцов тоже должны перадаваться в качестве параметров.

Не выйдет. Ни имя таблицы, ни имена столбцов нельзя передавать в качестве параметров.

Варианты решения:
1) отдельная процедура на каждую таблицу
2) свести все таблицы в одну



 
paxer   (2003-08-06 18:01) [14]

Спасибо.


 
kaif   (2003-08-06 23:13) [15]

Ну почему нельзя передавать в качестве параметра?
В лоб, конечно в IB нельзя. Но можно ведь сделать некий громадный IF внутри процедуры:

IF TABLE_NAME = "TABLE1" THEN
FOR SELECT * FROM TABLE1 INTO ... DO SUSPEND;
ELSE IF TABLE_NAME = "TABLE2" THEN
FOR SELECT * FROM TABLE2 INTO ... DO SUSPEND;
и так далее.
В принципе это тоже выход...
Хотя проще на клиентской части подставлять имя таблицы в текст запроса. :)


 
MDFE   (2003-08-07 04:16) [16]

для MSSQL (набросок)

CREATE PROCEDURE GET_DEPARTMENT_WITH_CHILDREN(
@MYID INTEGER
@IdName VARCHAR(20)
@IdParentName VARCHAR(20)
@TableName VARCHAR(20))
AS
DECLARE @aaa varchar(1024)

SET @aaa="select "+@idName+", "+@IdParentName+" from"+@TableName+" where"+@IdName+"="+Cast(@myid as varchar)+" into "+@fid+", "+@fname+", "+@fid_parent
EXEC(@aaa)
GO


т.е. собираем команду и запускаем (если возможно в IB)
?


 
MDFE   (2003-08-07 04:25) [17]

поправка на ночь...

SET @aaa="select "+@idName+", "+@IdParentName+" from"+@TableName+" where"+@IdName+"="+Cast(@myid as varchar)

:fname ?


 
Zacho   (2003-08-07 10:40) [18]

Небольшое дополнение: в FB 1.5 есть EXECUTE STATEMENT, EXECUTE STATEMENT INTO .. и FOR EXECUTE STATEMENT. Может, тебе имеет смысл перейти на FB 1.5, если действительно очень нужно передавать имена объектов метаданных в качестве параметров ?


 
Desdechado   (2003-08-07 11:03) [19]

перечисленное Zacho © (07.08.03 10:40) как раз и предназначено для обработки динамически создаваемых в ХП запросах (в т.ч. с использованием параметров)


 
Danilka   (2003-08-07 11:03) [20]

Zacho © (07.08.03 10:40)
Значит и в FB теперь есть динамический SQL?
Отлично, а то я так к нему привык, его отсутствие меня сильно смущало. :))


 
Zacho   (2003-08-07 11:08) [21]


> Danilka © (07.08.03 11:03)

Давно уже есть :-) Начиная с FB 1.5 Alpha 1, правда там оно еще называлось EXECUTE VARCHAR.
Release Notes надо время от времени читать :)


 
Danilka   (2003-08-07 11:23) [22]

Zacho © (07.08.03 11:08)
Дык, FB это просто увлечение, это я для себя что-то делаю в свободное от работы время, которого очень мало, с учетом просиженого времени в "потрепаться" :))



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2003.09.01;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.011 c
14-1622
keymaster
2003-08-13 15:06
2003.09.01
Формат PDF


14-1670
Шишкин Илья
2003-08-12 12:59
2003.09.01
Кто-нибудь разбирается в музыке?


14-1585
Феликс
2003-08-13 22:24
2003.09.01
Вы в курсе, что сегодня и завтра в Ин-нет лучше не выходить?


1-1444
Borealis
2003-08-18 18:10
2003.09.01
Позиция курсора в TEdit


14-1650
Khloo!
2003-08-11 13:42
2003.09.01
База данных...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский