是否可以创建一个存储过程,给定一个任意表,返回一个虚拟行?

时间:2016-05-13 19:20:10

标签: sql sql-server tsql database-design

我想知道是否可以创建像

这样的程序
CREATE PROCEDURE GetDummyRow 
    @table_name VARCHAR(128)
BEGIN
  -- ... 
END

插入名为@table_name的表中的虚拟行并从过程中返回它。期望@table_name具有主键。

例如,如果我有一个类似

的表格
==========================================
                Persons
============================================
 id | first_name | last_name    | spouse_id 
============================================
 1  |   "John"   |  "Skeet"     |     2 
 2  |   "Jane"   |  "Skeet"     |     1
 3  |  "Bjarne"  | "Stroustrup" |    NULL

使用

创建
CREATE TABLE Persons 
(
   id INT AUTO_INCREMEMENT,
   first_name VARCHAR(50) NOT NULL,
   last_name VARCHAR(50) NOT NULL,
   spouse_id INT,
   PRIMARY KEY id,
   FOREIGN KEY spouse_id REFERENCES Persons.id
)

我想要

DECLARE @t VARCHAR(128);
@t = 'Persons';
EXEC GetDummyRow(@t)

返回

4 | "ASDbaj" | "OEROANkaskoaASDOLJ" | NULL 

4 | "okasdALAJajdlaLashdasi" | "OEROANkaskoaASDOLJadasd" | 3 
例如,

有没有合理的理由说明为什么不可能做到这一点?

2 个答案:

答案 0 :(得分:0)

如果您可以使用默认值指定虚拟行的值,则可以大大简化。

CREATE TABLE Persons 
(
   id INT IDENTITY(1,1) NOT NULL,
   first_name VARCHAR(50) NOT NULL DEFAULT 'Dummy',
   last_name VARCHAR(50) NOT NULL DEFAULT 'Value',
   spouse_id INT
)
GO

CREATE PROCEDURE GetDummyRow (@table_name NVARCHAR(128))
AS
BEGIN
  DECLARE @sql nvarchar(MAX)
  SET @sql = N'INSERT INTO ' + @table_name + N' DEFAULT VALUES
  SELECT * FROM ' + @table_name + N' WHERE id = SCOPE_IDENTITY()'
  exec sp_executesql @sql  
END
GO

EXEC GetDummyRow 'Persons'

如果值必须是随机的,则可以使用NEWID()作为默认值:

CREATE TABLE Persons 
(
   id INT IDENTITY(1,1) NOT NULL,
   first_name VARCHAR(50) NOT NULL DEFAULT NEWID(),
   last_name VARCHAR(50) NOT NULL DEFAULT NEWID(),
   spouse_id INT
)
GO

http://sqlfiddle.com/#!3/85776/1

答案 1 :(得分:0)

要回答你的问题,没有理由认为这是不可能的。评论说它可能会变得复杂......

有一些要求不太清楚。当您说虚拟数据时,您不会说随机或唯一,但我猜您不希望每行都有相同的虚拟数据。这需要根据您希望支持的数据类型进行额外编码。

我会根据表架构创建一个游标。然后循环遍历列构建数据类型和约束/索引的代码。它是主键还是外键,是自动编号还是有检查约束。您可以从小规模开始并为不适合最期望类型的表/列构建异常处理。

根据数据库的体系结构和复杂性,您可以利用自动编号主键之类的功能。

如果有外键,您可以随机选择引用表中的键(即Top 1 ... From)或递归调用该过程以在该表中插入虚拟记录并返回新键。这需要将大部分功能放在一个返回主键的内部过程和一个返回您正在寻找的结果集的包装器中。

我相信这些链接将是一个良好的开端,查找主题将导致其他示例。

https://msdn.microsoft.com/en-us/library/ms186778.aspx

https://msdn.microsoft.com/en-us/library/ms177862.aspx