Форум: "Базы";
Текущий архив: 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