tmj*_*tmj 17 sql t-sql sql-server
像这样的代码,但它错了:
CREATE PROC sp_createATable
@name VARCHAR(10),
@properties VARCHAR(500)
AS
CREATE TABLE @name
(
id CHAR(10) PRIMARY KEY,
--...Properties extracted from @properties
);
Run Code Online (Sandbox Code Playgroud)
你能告诉我怎么处理吗?这真让我烦恼.
Nam*_*ian 44
您正在使用表变量,即您应该声明表.这不是临时表.
你创建一个像这样的临时表:
CREATE TABLE #customer
(
Name varchar(32) not null
)
Run Code Online (Sandbox Code Playgroud)
你声明一个表变量,如下所示:
DECLARE @Customer TABLE
(
Name varchar(32) not null
)
Run Code Online (Sandbox Code Playgroud)
请注意,临时表使用#声明,表变量使用@声明.去了解表变量和临时表之间的区别.
更新:
根据您在下面的评论,您实际上是在尝试在存储过程中创建表.为此,您需要使用动态SQL.基本上,动态SQL允许您以字符串的形式构造SQL语句,然后执行它.这是您能够在存储过程中创建表的唯一方法.我将向您展示如何,然后讨论为什么这通常不是一个好主意.
现在举一个简单的例子(我没有测试过这段代码,但它应该给你一个很好的指示,告诉你如何做):
CREATE PROCEDURE sproc_BuildTable
@TableName NVARCHAR(128)
,@Column1Name NVARCHAR(32)
,@Column1DataType NVARCHAR(32)
,@Column1Nullable NVARCHAR(32)
AS
DECLARE @SQLString NVARCHAR(MAX)
SET @SQString = 'CREATE TABLE '+@TableName + '( '+@Column1Name+' '+@Column1DataType +' '+@Column1Nullable +') ON PRIMARY '
EXEC (@SQLString)
GO
Run Code Online (Sandbox Code Playgroud)
这个存储过程可以像这样执行:
sproc_BuildTable 'Customers','CustomerName','VARCHAR(32)','NOT NULL'
这种类型的存储过程存在一些主要问题.
它很难满足复杂的桌子需求.想象一下下面的表格结构:
CREATE TABLE [dbo].[Customers] (
[CustomerID] [int] IDENTITY(1,1) NOT NULL,
[CustomerName] [nvarchar](64) NOT NULL,
[CustomerSUrname] [nvarchar](64) NOT NULL,
[CustomerDateOfBirth] [datetime] NOT NULL,
[CustomerApprovedDiscount] [decimal](3, 2) NOT NULL,
[CustomerActive] [bit] NOT NULL,
CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED
(
[CustomerID] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Customers] ADD CONSTRAINT [DF_Customers_CustomerApprovedDiscount] DEFAULT ((0.00)) FOR [CustomerApprovedDiscount]
GO
Run Code Online (Sandbox Code Playgroud)
这个表比第一个例子稍微复杂一点,但不是很多.处理存储过程会非常复杂得多.因此,虽然这种方法可能适用于小型表,但很快就会无法管理.
创建表需要规划.创建表时,应将它们策略性地放在不同的文件组中.这是为了确保您不会导致磁盘I/O争用.如果在主文件组上创建了所有内容,您将如何解决可伸缩性问题?
你能澄清为什么需要动态创建表吗?
更新2:
由于工作负载导致延迟更新.我读了你关于需要为每个商店创建一个表的评论,我认为你应该像我即将给你的例子那样做.
在这个例子中,我做了以下假设:
假设这个电子商务网站销售游戏机(即Wii,PS3,XBOX360).
看看我的假设,我看到了经典的多对多关系.商店可以出售许多商品(商品),商品(商品)可以在许多商店出售.让我们把它分解成表格.
首先,我需要一个商店桌来存储有关商店的所有信息.
一个简单的商店表可能如下所示:
CREATE TABLE [dbo].[Shop](
[ShopID] [int] IDENTITY(1,1) NOT NULL,
[ShopName] [nvarchar](128) NOT NULL,
CONSTRAINT [PK_Shop] PRIMARY KEY CLUSTERED
(
[ShopID] ASC
) WITH (
PAD_INDEX = OFF
, STATISTICS_NORECOMPUTE = OFF
, IGNORE_DUP_KEY = OFF
, ALLOW_ROW_LOCKS = ON
, ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)
让我们在数据库中插入三个商店,以便在我们的示例中使用.以下代码将插入三个商店:
INSERT INTO Shop
SELECT 'American Games R US'
UNION
SELECT 'Europe Gaming Experience'
UNION
SELECT 'Asian Games Emporium'
Run Code Online (Sandbox Code Playgroud)
如果执行a, SELECT * FROM Shop您可能会看到以下内容:
ShopID ShopName
1 American Games R US
2 Asian Games Emporium
3 Europe Gaming Experience
Run Code Online (Sandbox Code Playgroud)
是的,现在让我们转到Items(商品)表.由于物品/商品是各种公司的产品,我打算称之为产品.您可以执行以下代码来创建简单的Product表.
CREATE TABLE [dbo].[Product](
[ProductID] [int] IDENTITY(1,1) NOT NULL,
[ProductDescription] [nvarchar](128) NOT NULL,
CONSTRAINT [PK_Product] PRIMARY KEY CLUSTERED
(
[ProductID] ASC
)WITH (PAD_INDEX = OFF
, STATISTICS_NORECOMPUTE = OFF
, IGNORE_DUP_KEY = OFF
, ALLOW_ROW_LOCKS = ON
, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)
让我们用一些产品填充产品表.执行以下代码以插入一些产品:
INSERT INTO Product
SELECT 'Wii'
UNION
SELECT 'PS3'
UNION
SELECT 'XBOX360'
Run Code Online (Sandbox Code Playgroud)
如果执行,SELECT * FROM Product您可能会看到以下内容:
ProductID ProductDescription
1 PS3
2 Wii
3 XBOX360
Run Code Online (Sandbox Code Playgroud)
好的,此时您同时拥有产品和商店信息.那你怎么把它们组合在一起呢?我们知道我们可以通过其ShopID主键列识别商店,我们知道我们可以通过其ProductID主键列识别产品.此外,由于每个商店对每种产品都有不同的价格,我们需要存储商店为产品收取的价格.
所以我们有一张表将商店映射到产品.我们将此表称为ShopProduct.此表的简单版本可能如下所示:
CREATE TABLE [dbo].[ShopProduct](
[ShopID] [int] NOT NULL,
[ProductID] [int] NOT NULL,
[Price] [money] NOT NULL,
CONSTRAINT [PK_ShopProduct] PRIMARY KEY CLUSTERED
(
[ShopID] ASC,
[ProductID] ASC
)WITH (PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)
因此,我们假设American Games R Us商店仅销售美国游戏机,Europe Gaming Experience销售所有游戏机,而Asian Games Emporium仅销售亚洲游戏机.我们需要将商店和产品表中的主键映射到ShopProduct表中.
以下是我们如何进行映射.在我的例子中,American Games R Us的ShopID值为1(这是主键值),我可以看到XBOX360的值为3,商店已经列出了XBOX360,价格为159.99美元
通过执行以下代码,您将完成映射:
INSERT INTO ShopProduct VALUES(1,3,159.99)
Run Code Online (Sandbox Code Playgroud)
现在我们想要将所有产品添加到Europe Gaming Experience商店.在这个例子中,我们知道Europe Gaming Experience商店的ShopID为3,因为它销售所有控制台,我们需要将ProductID 1,2和3插入到映射表中.让我们假设欧洲游戏体验店的游戏机(产品)价格如下:1- PS3的售价为259.99美元,2-Wii的售价为159.99美元,3- XBOX360的售价为199.99美元.
要完成此映射,您需要执行以下代码:
INSERT INTO ShopProduct VALUES(3,2,159.99) --This will insert the WII console into the mapping table for the Europe Gaming Experience Shop with a price of 159.99
INSERT INTO ShopProduct VALUES(3,1,259.99) --This will insert the PS3 console into the mapping table for the Europe Gaming Experience Shop with a price of 259.99
INSERT INTO ShopProduct VALUES(3,3,199.99) --This will insert the XBOX360 console into the mapping table for the Europe Gaming Experience Shop with a price of 199.99
Run Code Online (Sandbox Code Playgroud)
此时,您已将两个商店及其产品映射到映射表中.好的,那么现在如何将这些全部组合在一起以显示用户浏览网站?假设您想要在网页上向用户显示欧洲游戏体验的所有产品 - 您需要执行以下查询:
SELECT Shop.*
, ShopProduct.*
, Product.*
FROM Shop
INNER JOIN ShopProduct ON Shop.ShopID = ShopProduct.ShopID
INNER JOIN Product ON ShopProduct.ProductID = Product.ProductID
WHERE Shop.ShopID=3
Run Code Online (Sandbox Code Playgroud)
您可能会看到以下结果:
ShopID ShopName ShopID ProductID Price ProductID ProductDescription
3 Europe Gaming Experience 3 1 259.99 1 PS3
3 Europe Gaming Experience 3 2 159.99 2 Wii
3 Europe Gaming Experience 3 3 199.99 3 XBOX360
Run Code Online (Sandbox Code Playgroud)
现在,最后一个例子,我们假设您的网站有一个功能,可以找到最便宜的控制台价格.用户要求查找XBOX360的最低价格.
您可以执行以下查询:
SELECT Shop.*
, ShopProduct.*
, Product.*
FROM Shop
INNER JOIN ShopProduct ON Shop.ShopID = ShopProduct.ShopID
INNER JOIN Product ON ShopProduct.ProductID = Product.ProductID
WHERE Product.ProductID =3 -- You can also use Product.ProductDescription = 'XBOX360'
ORDER BY Price ASC
Run Code Online (Sandbox Code Playgroud)
此查询将返回所有商店的列表,这些商店首先以最便宜的商店销售XBOX360,依此类推.
您会注意到我没有添加亚运商店.作为练习,将亚洲游戏商店添加到地图表中,其中包括以下产品:亚运商场以99.99美元的价格销售Wii游戏机,以159.99美元的价格销售PS3游戏机.如果您通过此示例,您现在应该了解如何建立多对多关系的模型.
我希望这可以帮助您在数据库设计中旅行.
| 归档时间: |
|
| 查看次数: |
134978 次 |
| 最近记录: |