Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Insert Execute внутри функции возвращающей таблицу  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
Привет.

Подскажите пожалуйста как быть.

У меня есть штук 5 таблиц. Данные в них однотипные.
Мне нужно из процедуры возвращать данные из этих таблиц - например все ID шники.

Чтобы не зашивать все жестко в код по типу:
if @TypeId = 1
  INSERT INTO @Ids
  SELECT id FROM [Tab1]
else if @TypeId = 2
  INSERT INTO @Ids
  SELECT id FROM [Tab2]


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

Теперь я хочу написать такую функцию:

CREATE FUNCTION [Gs].[GetIds](@TypeId int)
RETURNS @OrgsTab TABLE
   (
    Id		int,
    Inn	nvarchar(max),
    Kpp	nvarchar(max)
   )
AS
BEGIN  
declare @DynamicSelect nvarchar(max)  
  declare @Ids TABLE(
    id int NOT NULL
  );

  set @DynamicSelect = 'select id from '+ (select Title from [Gs].[EntityType] where [Id] = @TypeId) 

  INSERT @OrganizationsTab execute (@DynamicSelect)
 ...


но получаю ошибку:
Msg 443, Level 16, State 14, Procedure GetIds, Line 26
Invalid use of a side-effecting operator 'INSERT EXEC' within a function.



Как мне быть ? Как сделать свою задумку ?
22 окт 15, 18:42    [18313686]     Ответить | Цитировать Сообщить модератору
 Re: Insert Execute внутри функции возвращающей таблицу  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
Звиняюсь. Селектится динамиком так:

 INSERT @Ids execute (@DynamicSelect)


Это я уже экспериментирую, и написал чушь "INSERT @OrganizationsTab"
22 окт 15, 18:45    [18313699]     Ответить | Цитировать Сообщить модератору
 Re: Insert Execute внутри функции возвращающей таблицу  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
Если так действительно нельзя писать в функциях - то каким еще способом можно решить мою идею ?

Ну не очень хочется зашивать в код имена таблиц и привязку вида "если 1, то селектить нужно из первой таблиц, а если 2, то из второй".
Согласитесь же, что проще в одной таблице поменять/добавить имена таблиц, а не лезть в процедуру и дописывать код !
22 окт 15, 18:49    [18313714]     Ответить | Цитировать Сообщить модератору
 Re: Insert Execute внутри функции возвращающей таблицу  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
А нефига однотипные данные хранить в пяти разных таблицах, когда для этого достаточно одной.
22 окт 15, 18:52    [18313725]     Ответить | Цитировать Сообщить модератору
 Re: Insert Execute внутри функции возвращающей таблицу  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
Гавриленко Сергей Алексеевич,

Не от меня зависит.
Такова схема данных. Разные схемы в БД, но данные там однотипные - ОРГАНИЗАЦИИ. У них есть ИНН и КПП.

Моя процедура должна вернуть эти данные об ОРГАНИЗАЦИЯХ. Ну и что мне делать, если они в разных таблицах и схемах.
22 окт 15, 18:54    [18313731]     Ответить | Цитировать Сообщить модератору
 Re: Insert Execute внутри функции возвращающей таблицу  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
ProBiotek
Гавриленко Сергей Алексеевич,

Не от меня зависит.
Такова схема данных. Разные схемы в БД, но данные там однотипные - ОРГАНИЗАЦИИ. У них есть ИНН и КПП.

Моя процедура должна вернуть эти данные об ОРГАНИЗАЦИЯХ. Ну и что мне делать, если они в разных таблицах и схемах.
Написать view и селектить данные из нее.
22 окт 15, 18:55    [18313738]     Ответить | Цитировать Сообщить модератору
 Re: Insert Execute внутри функции возвращающей таблицу  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
Гавриленко Сергей Алексеевич
Написать view и селектить данные из нее.


хм. а это мысль.

Базовые вещи по БД ускользают от моего внимания, т.к. я больше по C# - и чаще проекты не связанны базами, или все очень простое там.
22 окт 15, 18:57    [18313747]     Ответить | Цитировать Сообщить модератору
 Re: Insert Execute внутри функции возвращающей таблицу  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
Гавриленко Сергей Алексеевич,

Стоп. Но проблема то остается.
Мне нужно селектить из разных таблиц - и селект получать динамиком.

Во вьюхах можно использовать динамик ?
Если нет, что чем вьюха будет лучше моей процедуры:

if @TypeId = 1
  INSERT INTO @Ids
  SELECT id FROM [Tab1]
else if @TypeId = 2
  INSERT INTO @Ids
  SELECT id FROM [Tab2]


?
22 окт 15, 19:04    [18313772]     Ответить | Цитировать Сообщить модератору
 Re: Insert Execute внутри функции возвращающей таблицу  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Написшите во view:
  SELECT <поля> FROM [Tab1]
  union all
  SELECT <поля> FROM [Tab2]
  union all
  SELECT <поля> FROM [Tab3]
  union all
  SELECT <поля> FROM [Tab4]
  union all
  SELECT <поля> FROM [Tab5]


После просто выбирайте из нее как из одной таблицы.

Сообщение было отредактировано: 22 окт 15, 19:07
22 окт 15, 19:07    [18313780]     Ответить | Цитировать Сообщить модератору
 Re: Insert Execute внутри функции возвращающей таблицу  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Если надо разделять таблицы по типам, то добавьте соответствующее поле в список полей и по нему фильтруйте.
22 окт 15, 19:08    [18313784]     Ответить | Цитировать Сообщить модератору
 Re: Insert Execute внутри функции возвращающей таблицу  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
Гавриленко Сергей Алексеевич,

Это то я понял.

Но вы смотрите какая ситуация: где то нужно хранить связку, что 1 - это Tab1, а 2 - это Tab2.

Для того, чтобы юзер мог выбрать что "я хочу получить организации из схемы такой то" - и программа должна как-то выяснить, что "схема такая то закреплена за 1".

Понимаете как хрупко выходит ? Нужно поддерживать эту связку.

Я то хотел, чтобы была таблица:
id UserReadableTitle TableName
1 Организации из схемы 1 [Tab2]


Чтобы можно было юзеру дать выпадающий список полей UserReadableTitle и автоматически получать связку.


В вашем решении нам нужно поддерживать две сущности:
1.
id UserReadableTitle TableName
1 Организации из схемы 1 [Tab2]

2.
Гавриленко Сергей Алексеевич
добавьте соответствующее поле в список полей и по нему фильтруйте.


поддерживать в синхронизированном состоянии две сущности то сложнее, чем когда она единственная и синхронизация не нужна !
22 окт 15, 19:16    [18313803]     Ответить | Цитировать Сообщить модератору
 Re: Insert Execute внутри функции возвращающей таблицу  [new]
o-o
Guest
Гавриленко Сергей Алексеевич
Написшите во view:
  SELECT <поля>,  'tab1'as table_name FROM [Tab1]
  union all
  SELECT <поля>, 'tab2' FROM [Tab2]
  union all
  SELECT <поля>,  'tab3' FROM [Tab3]
  union all
  SELECT <поля>,  'tab4' FROM [Tab4]
  union all
  SELECT <поля>,  'tab5' FROM [Tab5]



одна сущность
22 окт 15, 19:40    [18313875]     Ответить | Цитировать Сообщить модератору
 Re: Insert Execute внутри функции возвращающей таблицу  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
o-o,

Но тут пролетает ID.
Неясно как ссылаться на эту таблицу.

Ну ок. я подумаю.
22 окт 15, 19:57    [18313916]     Ответить | Цитировать Сообщить модератору
 Re: Insert Execute внутри функции возвращающей таблицу  [new]
правильный проходящий.
Guest
ProBiotek
o-o,

Но тут пролетает ID.
Где пролетает? Куда пролетает? Что в вашем понимании есть "пролетает"?
Неясно как ссылаться на эту таблицу.
На какую ЭТУ? Что значит ссылаться и зачем тут на что-то ссылаться?
22 окт 15, 20:06    [18313951]     Ответить | Цитировать Сообщить модератору
 Re: Insert Execute внутри функции возвращающей таблицу  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32167
ProBiotek
Но тут пролетает ID.
Неясно как ссылаться на эту таблицу.
Непонятна всё таки проблема.
Во view добавляете поле TypeId

Во всех запросах пишите вместо:
ProBiotek
if @TypeId = 1
  INSERT INTO @Ids
  SELECT id FROM [Tab1]
else if @TypeId = 2
  INSERT INTO @Ids
  SELECT id FROM [Tab2]

вот так:
INSERT INTO @Ids
SELECT id FROM [ваша вьюха]
WHERE TypeId = @TypeId
22 окт 15, 20:09    [18313960]     Ответить | Цитировать Сообщить модератору
 Re: Insert Execute внутри функции возвращающей таблицу  [new]
invm
Member

Откуда: Москва
Сообщений: 9913
ProBiotek
Неясно как ссылаться на эту таблицу.
create function dbo.fnGetTableData
(
 @Table sysname
)
returns table
as
return (
  SELECT <поля> FROM [Tab1] where @Table = N'Tab1'
  union all
  SELECT <поля> FROM [Tab2] where @Table = N'Tab2'
  union all
  SELECT <поля> FROM [Tab3] where @Table = N'Tab3'
  union all
  SELECT <поля> FROM [Tab4] where @Table = N'Tab4'
  union all
  SELECT <поля> FROM [Tab5] where @Table = N'Tab5'
);
22 окт 15, 20:15    [18313977]     Ответить | Цитировать Сообщить модератору
 Re: Insert Execute внутри функции возвращающей таблицу  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
invm,

Функция хуже представления в случае, когда надо что=то найти во всех таблицах.
22 окт 15, 20:19    [18313995]     Ответить | Цитировать Сообщить модератору
 Re: Insert Execute внутри функции возвращающей таблицу  [new]
invm
Member

Откуда: Москва
Сообщений: 9913
Гавриленко Сергей Алексеевич
Функция хуже представления в случае, когда надо что=то найти во всех таблицах.
Несомненно. Но ТС'у, судя по стартовому посту, нужно обращаться к одной таблице.
А вообще, можно написать одну функцию под оба случая:
create function dbo.fnGetTablesData
(
 @Table sysname
)
returns table
as
return (
  SELECT <поля> FROM [Tab1] where isnull(@Table, N'Tab1') = N'Tab1'
  union all
  SELECT <поля> FROM [Tab2] where isnull(@Table, N'Tab2') = N'Tab2'
  union all
  SELECT <поля> FROM [Tab3] where isnull(@Table, N'Tab3') = N'Tab3'
  union all
  SELECT <поля> FROM [Tab4] where isnull(@Table, N'Tab4') = N'Tab4'
  union all
  SELECT <поля> FROM [Tab5] where isnull(@Table, N'Tab5') = N'Tab5'
);
22 окт 15, 20:46    [18314061]     Ответить | Цитировать Сообщить модератору
 Re: Insert Execute внутри функции возвращающей таблицу  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
invm
А вообще, можно написать одну функцию под оба случая
Мне вьюха больше нравится. Потому что ее можно материализовать. xD
23 окт 15, 00:47    [18314713]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить