Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Проблемы с INSERT INTO EXEC SP (MS SQL Server 2012 MSSQLEXPRESS) / 12 сообщений из 12, страница 1 из 1
12.02.2020, 14:15
    #39925713
MsGuns
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с INSERT INTO EXEC SP (MS SQL Server 2012 MSSQLEXPRESS)
Здравствуйте, форумчане !

Есть SP, которая по полученным параметрам делает выборку, сортировку
и нумерацию записей из некоторой таблицы БД. Вот она:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
USE [SQLMVCPar]
GO
/****** Object:  StoredProcedure [dbo].[UsP_SFN]    Script Date: 12.02.2020 12:21:27 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- Извлекает записи из полной телефонной Книги с применением указанного фильтра,
-- упорядочивает их по указанной колонке, нумерует их по порядку (с 1),
-- добавляет в хвост НД колонку NROW, куда помещает порядковый номер строки 
ALTER PROCEDURE [dbo].[UsP_SFN]
	@FilterColName sysname,  -- Имя колонки, по которой будет выборка (фильтрация)
    @OrderColName sysname,   -- Имя колонки, по которой будет упорядочен НД
    @FilterValue varchar(max), -- Значение - образец для фильтра
    @OrderDirection varchar(4) -- ASC - по возрастанию, DESC - по убыванию

AS
BEGIN
  SET NOCOUNT ON;

DECLARE @SQLStr nvarchar(2000)

IF OBJECT_ID (N'Tmp', N'U') IS NOT NULL DROP TABLE Tmp

  SET @SQLStr = N'SELECT Row_No ,Region_Cuntry, No_Cell, No_Fix, FLN, Name_Pos, Name_TO, [Address],
      ROW_NUMBER() OVER(ORDER BY ' + @OrderColName + ' ' + @OrderDirection + ') as NROW INTO Tmp FROM _TelBook '
  IF @FilterColName > ''
     SET @SQLStr = @SQLStr + N'WHERE ' + @FilterColName + ' = ''' + @FilterValue + ''''

--  SELECT @SQLStr
  EXEC (@SQLStr)
  
  SELECT * from Tmp
  DROP TABLE Tmp

END


Все работает отлично.

Требуется создать SP, которая будет выбирать из НД, полученного вышеуказанной SP, нужную страницу

Вот скрипт - контент для этой SP

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
--sp_configure 'show advanced options', 1;  
--RECONFIGURE;
--GO 
--sp_configure 'Ad Hoc Distributed Queries', 1;  
--RECONFIGURE;  
--GO  

use SQLMVCPar
begin

  DECLARE @FilterColName sysname
  DECLARE @OrderColName sysname
  DECLARE @FilterValue varchar(max)
  DECLARE @OrderDirection varchar(4)

  DECLARE @NPage int
  DECLARE @QRowsAtPage int
  DECLARE @SQLExec varchar(max)
  DECLARE @SQL varchar(max)

  SET @FilterColName = 'Name_TO'
  SET @OrderColName = 'FLN'
  SET @FilterValue = N'Филиал в пгт. Пеньково'
  SET @OrderDirection = 'ASC'

  SET @NPage = 1
  SET @QRowsAtPage = 10


  IF OBJECT_ID (N'Tmp', N'U') IS NOT NULL DROP TABLE Tmp

  CREATE TABLE dbo.Tmp(
	[Row_No] [nvarchar](255) NULL,
	[Region_Cuntry] [nvarchar](255) NULL,
	[No_Cell] [nvarchar](255) NULL,
	[No_Fix] [nvarchar](255) NULL,
	[FLN] [nvarchar](255) NULL,
	[Name_Pos] [nvarchar](255) NULL,
	[Name_TO] [nvarchar](255) NULL,
	[Address] [nvarchar](255) NULL,
	[NROW] [bigint] NULL
    ) ON [PRIMARY]

  INSERT INTO dbo.Tmp
  Exec UsP_SFN @FilterColName, @OrderColName, @FilterValue, @OrderDirection

--  SET @SQLExec = 'Exec UsP_SFN ''' + @FilterColName + ''',''' + @OrderColName +''',''' + @FilterValue + ''',''' + @OrderDirection + '';
--  SET @SQL = ' Select * into Tmp from OPENROWSET(''SQLNCLI'',''Server=MSGUNS-PC\MSSQLEXPRESS;Trusted_Connection=yes;'',N'''+ @SQLExec + ''');'

--  select @SQL
--  Exec (@SQL)

  SELECT * from tmp
    Where NROW > (@NPage-1)*@QRowsAtPage AND NROW < @NPage*@QRowsAtPage + 1
  DROP TABLE tmp

end


При запуске выдает:

Сообщение 556, уровень 16, состояние 3, строка 44
Ошибка при выполнении INSERT EXEC, поскольку хранимая процедура изменила схему целевой таблицы.

Почитал, что такая ошибка возникает из-за особенностей очистки MS SQL Server хранилища
( https://support.microsoft.com/ru-ru/help/4465511/error-556-insert-exec-failed-stored-procedure-altered-table-schema)

Также почитал о "подводных камнях Insert Exec" здесь:
https://olontsev.ru/2016/05/insert-exec-behaviour/

Как избавиться от ошибки я так и не понял (видимо из-за "особенностей" автоперевода на сайте Microsoft)
Решил пойти другим путем: использовать OPENROWSET, опыта работы с которым совсем не имею.
Но возникла новая проблема: дело в том, что "базовая" SP требует параметры-строки. Попытка вставить их в строку для OpenRowset привела к тому, что вместо трех параметров - строк, OpenRowSet получает 7 и естественно опять ошибка.

Как решить проблему ? Замена базовой SP на функцию невозможна из-за динамического SQL
...
Рейтинг: 0 / 0
12.02.2020, 14:20
    #39925717
andy st
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с INSERT INTO EXEC SP (MS SQL Server 2012 MSSQLEXPRESS)
MsGuns,
Код: sql
1.
DROP TABLE Tmp

в процедуре, которая пишет в эту же таблицу?
даже страшно предположить, что вы там курите
...
Рейтинг: 0 / 0
12.02.2020, 14:41
    #39925736
StarikNavy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с INSERT INTO EXEC SP (MS SQL Server 2012 MSSQLEXPRESS)
MsGuns,

#tmp
...
Рейтинг: 0 / 0
12.02.2020, 15:02
    #39925751
MsGuns
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с INSERT INTO EXEC SP (MS SQL Server 2012 MSSQLEXPRESS)
Спасибо огромное !
А ларчик просто открывался :)

Дурные отрыжки копипасты :)
Ну и замена постоянной таблицы на временную тоже..

Трава обычная :)
Надо обойти кривости мсскл, в частности невозможность использования в UDF динамического SQL, а также вызова SP из UDF. Все приходится делать в хранимках.

Таблица создается как временное хранилище для того, чтобы всунуть туда выборку и вернуть ее вовне. После чего таблица удаляется. Что-то типа курсора :) Т.к. все это в рамках одной транзакции, то конфликтов вроде как быть не должно.
...
Рейтинг: 0 / 0
12.02.2020, 15:43
    #39925777
Ролг Хупин
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с INSERT INTO EXEC SP (MS SQL Server 2012 MSSQLEXPRESS)
MsGuns
Спасибо огромное !
А ларчик просто открывался :)

Дурные отрыжки копипасты :)
Ну и замена постоянной таблицы на временную тоже..

Трава обычная :)
Надо обойти кривости мсскл, в частности невозможность использования в UDF динамического SQL, а также вызова SP из UDF. Все приходится делать в хранимках.

Таблица создается как временное хранилище для того, чтобы всунуть туда выборку и вернуть ее вовне. После чего таблица удаляется. Что-то типа курсора :) Т.к. все это в рамках одной транзакции, то конфликтов вроде как быть не должно.


"кривой" мсскл грустно курит в углу бычки и наблюдает как чёткие девелоперы курят траву и обходят его "кривости"
...
Рейтинг: 0 / 0
12.02.2020, 17:11
    #39925875
Владислав Колосов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с INSERT INTO EXEC SP (MS SQL Server 2012 MSSQLEXPRESS)
MsGuns,

Код: sql
1.
в частности невозможность использования в UDF динамического SQL, а также вызова SP из UDF



да нет, же забористая у вас трава. Вы откуда образование разработчика СУБД получили - из Pascal или Basic?
...
Рейтинг: 0 / 0
12.02.2020, 17:57
    #39925920
MsGuns
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с INSERT INTO EXEC SP (MS SQL Server 2012 MSSQLEXPRESS)
>да нет, же забористая у вас трава. Вы откуда образование разработчика СУБД получили - из Pascal или Basic?

1. Какое отношение ЯП имеет к СУБД ?
2. Если речь идет о СУБД, то мой опыт такой: Clipper, Paradox, Interbase(Firebird), MS SQL, Oracle, PostgreSQL, MySQL
Правда, экспертом ни в одной из этих СУБД не являюсь. Просто пришлось работать с этими дядьками.
3. Пилюля получена и съедена. А где эффект, т.е. где ссылка (хотя бы) на разъяснение каков я дурак ?
Или плюнул и пошел ?
...
Рейтинг: 0 / 0
12.02.2020, 18:05
    #39925926
MsGuns
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с INSERT INTO EXEC SP (MS SQL Server 2012 MSSQLEXPRESS)
...
Рейтинг: 0 / 0
12.02.2020, 18:12
    #39925930
Владислав Колосов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с INSERT INTO EXEC SP (MS SQL Server 2012 MSSQLEXPRESS)
MsGuns,

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

Код: sql
1.
2.
  SET @SQLStr = N'SELECT Row_No ,Region_Cuntry, No_Cell, No_Fix, FLN, Name_Pos, Name_TO, [Address],
      ROW_NUMBER() OVER(ORDER BY ' + @OrderColName + ' ' + @OrderDirection + ') as NROW INTO Tmp FROM _TelBook '



такие запросы плохо работают при массовой нагрузке на сервер, хотя и допустимы при редких единичных выполнениях. Произвольная сортировка и нумерация строк довольно часто выполняется в клиентском приложении, т.к. это работает быстрее как с точки зрения извлечения данных, так и с точки зрения сортировки.
...
Рейтинг: 0 / 0
12.02.2020, 19:12
    #39925956
MsGuns
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с INSERT INTO EXEC SP (MS SQL Server 2012 MSSQLEXPRESS)
Исходная "таблица" - это что-то вроде Корпоративной телефонной Книги с массой дополнительных атрибутов. Вся эта "кухня" хранится не в одной таблице, конечно, и даже не в десяти. В итоге записей в этой книге несколько сот тысяч. Число пользователей приложения исчисляется тысячами в один момент времени. Выборка всей Книги не нужна в принципе - поэтому используются "фильтры" (Where), число которых весьма велико (более 20). Писать в UDF все эти кейсы - это ж... Тем более, что так и есть в настоящий момент. В результате UDF-ки огроменные и их дофига и больше. Я хочу несколько "облегчить" логику пусть даже ценою некоторой потери производительности. Проект и так слишком "тяжел" и на его сопровождение и развитие уходит до черта ресурсов (читай - денег). В конце концов докупить пару серверов много проще, чем найти квалифицированного программиста взамен ушедшего.
...
Рейтинг: 0 / 0
12.02.2020, 19:16
    #39925960
msLex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с INSERT INTO EXEC SP (MS SQL Server 2012 MSSQLEXPRESS)
MsGuns
Исходная "таблица" - это что-то вроде Корпоративной телефонной Книги с массой дополнительных атрибутов. Вся эта "кухня" хранится не в одной таблице, конечно, и даже не в десяти. В итоге записей в этой книге несколько сот тысяч. Число пользователей приложения исчисляется тысячами в один момент времени. Выборка всей Книги не нужна в принципе - поэтому используются "фильтры" (Where), число которых весьма велико (более 20). Писать в UDF все эти кейсы - это ж... Тем более, что так и есть в настоящий момент. В результате UDF-ки огроменные и их дофига и больше. Я хочу несколько "облегчить" логику пусть даже ценою некоторой потери производительности. Проект и так слишком "тяжел" и на его сопровождение и развитие уходит до черта ресурсов (читай - денег). В конце концов докупить пару серверов много проще, чем найти квалифицированного программиста взамен ушедшего.

Замените udf на процедуры и делайте там свои динамические запросы.
...
Рейтинг: 0 / 0
12.02.2020, 20:13
    #39925985
MsGuns
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблемы с INSERT INTO EXEC SP (MS SQL Server 2012 MSSQLEXPRESS)
msLex
MsGuns
Исходная "таблица" - это что-то вроде Корпоративной телефонной Книги с массой дополнительных атрибутов. Вся эта "кухня" хранится не в одной таблице, конечно, и даже не в десяти. В итоге записей в этой книге несколько сот тысяч. Число пользователей приложения исчисляется тысячами в один момент времени. Выборка всей Книги не нужна в принципе - поэтому используются "фильтры" (Where), число которых весьма велико (более 20). Писать в UDF все эти кейсы - это ж... Тем более, что так и есть в настоящий момент. В результате UDF-ки огроменные и их дофига и больше. Я хочу несколько "облегчить" логику пусть даже ценою некоторой потери производительности. Проект и так слишком "тяжел" и на его сопровождение и развитие уходит до черта ресурсов (читай - денег). В конце концов докупить пару серверов много проще, чем найти квалифицированного программиста взамен ушедшего.

Замените udf на процедуры и делайте там свои динамические запросы.


А вот Владислав Колосов придерживается противоположного мнения :)
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Проблемы с INSERT INTO EXEC SP (MS SQL Server 2012 MSSQLEXPRESS) / 12 сообщений из 12, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]