Возврат динамической таблицы SQL из функции или хранимой процедуры для использования в запросе - PullRequest
2 голосов
/ 06 ноября 2019

У меня есть несколько таблиц, в которых есть поле «Удаленные» типа DATETIME, которое я использую, чтобы пометить записи как удаленные (а не полностью удаляя их).

Я часто запрашиваю данные из этих таблици желая исключить удаленные записи. Сейчас я делаю что-то вроде:

SELECT A.* 
FROM (SELECT * FROM [TargetTable] WHERE (Deleted IS NULL)) AS A
WHERE (.........)

Возможно ли иметь хранимую процедуру / функцию, которой я могу передать имя таблицы и вернуть отфильтрованную таблицу? Что-то вроде:

SELECT A.*
FROM fnExcludeDeleted('MyTable') AS A
WHERE (.........)

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

1 Ответ

0 голосов
/ 06 ноября 2019

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

Эта хранимая процедура основана на следующих шагах;

  1. Создание сценария объявленной таблицы
  2. Созданиеглобальное временное, сформированное с той же структурой, что и объявленная таблица
  3. Заполнение исходных данных таблицы во временную таблицу
  4. Возвращение набора результатов временной таблицы

Примечание: В этом запросе используется хранимая процедура GetTableCreateScript для получения объявленного сценария создания таблицы.

РЕДАКТИРОВАНИЕ: STRING_AGG удалено дляболее низкая версия SQL Server 2017 и добавлена ​​XML PATH для объединения строк.

  DROP TABLE IF EXISTS TargetTable1
GO
CREATE TABLE TargetTable1 (Col1 INT , Deleted DATE)
GO
---Populating test data---
INSERT INTO TargetTable1 VALUES (1,GETDATE())
INSERT INTO TargetTable1 VALUES (2,NULL)
INSERT INTO TargetTable1 VALUES (3,GETDATE())
INSERT INTO TargetTable1 VALUES (4,NULL)
GO
CREATE OR ALTER PROC DynamicSQL 
@TableName AS VARCHAR(200)
AS
DROP TABLE IF EXISTS  ##TempDynamic
DECLARE @SQLDynamicTable AS VARCHAR(MAX)
DECLARE @SQLDynamicRows AS VARCHAR(MAX)
CREATE TABLE #DynamicSQL (S VARCHAR(MAX))


INSERT INTO #DynamicSQL
EXEC    [dbo].GetTableCreateScript @TableName --->Generate Table Definition
---You can find GetTableCreateScript  create script https://www.c-sharpcorner.com/blogs/generate-table-defination-in-sql-server-without-gui

--SELECT @SQLDynamicTable=REPLACE(STRING_AGG(S,' '),@TableName, '##TempDynamic') FROM #DynamicSQL ----->Create TempTable for SQL Server 2017 and upper version

SELECT  @SQLDynamicTable=STUFF((
         SELECT ' ' + s
            FROM #DynamicSQL 
            FOR XML PATH('')
         ), 1, 1, '')


SET @SQLDynamicTable = REPLACE(@SQLDynamicTable,@TableName, '##TempDynamic')
PRINT @SQLDynamicTable
EXEC (@SQLDynamicTable)
SET @SQLDynamicRows = 'INSERT INTO ##TempDynamic SELECT * FROM ' + @TableName
EXEC(@SQLDynamicRows)
SELECT * FROM ##TempDynamic
WHERE Deleted IS NULL

GO 
EXEC DynamicSQL 'TargetTable1'



    +------+---------+
    | Col1 | Deleted |
    +------+---------+
    |    2 | NULL    |
    |    4 | NULL    |
    +------+---------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...