テーブル変数を使用しています。つまり、テーブルを宣言する必要があります。これは一時テーブルではありません。
次のように一時テーブルを作成します。
CREATE TABLE #customer
(
Name varchar(32) not null
)
次のようにテーブル変数を宣言します。
DECLARE @Customer TABLE
(
Name varchar(32) not null
)
一時テーブルは # を使用して宣言され、テーブル変数は @ を使用して宣言されていることに注意してください。テーブル変数と一時テーブルの違いについて読んでください。
アップデート:
以下のコメントに基づいて、実際にストアド プロシージャでテーブルを作成しようとしています。このためには、動的 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
このストアド プロシージャは、次のように実行できます。
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
この表は最初の例より少し複雑ですが、それほど多くはありません。ストアド プロシージャの処理は、はるかに複雑になります。したがって、このアプローチは小さなテーブルでは機能するかもしれませんが、すぐに管理できなくなります。
テーブルの作成には計画が必要です。テーブルを作成するときは、異なるファイル グループに戦略的に配置する必要があります。これは、ディスク I/O の競合が発生しないようにするためです。すべてがプライマリ ファイル グループ上に作成されている場合、スケーラビリティにどのように対処しますか?
テーブルを動的に作成する必要がある理由を明確にしていただけますか?
更新 2:
仕事の都合で更新が遅くなりました。ショップごとにテーブルを作成する必要があるというコメントを読みましたが、これから紹介する例のように作成することを検討する必要があると思います。
この例では、次の仮定を行います。
- ショップ数が多いECサイトです
- ショップは、販売する多くのアイテム (商品) を持つことができます。
- 特定の商品(商品)を多くの店で販売できる
- ショップは、アイテム (商品) ごとに異なる価格を請求します。
- すべての価格は $ (USD) です
この e コマース サイトがゲーム コンソール (つまり、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
この例で使用する 3 つの店舗をデータベースに挿入してみましょう。次のコードは、3 つのショップを挿入します。
INSERT INTO Shop
SELECT 'American Games R US'
UNION
SELECT 'Europe Gaming Experience'
UNION
SELECT 'Asian Games Emporium'
a を実行する と、SELECT * FROM Shop
おそらく次のように表示されます。
ShopID ShopName
1 American Games R US
2 Asian Games Emporium
3 Europe Gaming Experience
では、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
products テーブルにいくつかの製品を入力してみましょう。次のコードを実行して、いくつかの製品を挿入します。
INSERT INTO Product
SELECT 'Wii'
UNION
SELECT 'PS3'
UNION
SELECT 'XBOX360'
実行SELECT * FROM Product
すると、おそらく次のように表示されます。
ProductID ProductDescription
1 PS3
2 Wii
3 XBOX360
OK、この時点で、製品とショップの両方の情報が得られました。では、それらをどのようにまとめますか?ShopID 主キー列でショップを識別できることはわかっていますし、ProductID 主キー列で製品を識別できることもわかっています。また、ショップごとに商品ごとに異なる価格が設定されているため、ショップが商品に対して請求する価格を保存する必要があります。
これで、Shop を製品にマップするテーブルができました。このテーブルを 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
そこで、American Games R Us ショップがアメリカのコンソールのみを販売し、Europe Gaming Experience がすべてのコンソールを販売し、Asian Games Emporium がアジアのコンソールのみを販売していると仮定しましょう。shop テーブルと product テーブルの主キーを ShopProduct テーブルにマップする必要があります。
ここでは、マッピングを行う方法について説明します。私の例では、American Games R Us の ShopID 値は 1 (これが主キーの値です) で、XBOX360 の値は 3 で、ショップは XBOX360 を $159.99 でリストしています。
次のコードを実行すると、マッピングが完了します。
INSERT INTO ShopProduct VALUES(1,3,159.99)
ここで、すべての製品を Europe Gaming Experience ショップに追加したいと考えています。この例では、Europe Gaming Experience ショップの ShopID が 3 であることがわかっており、すべてのコンソールを販売しているため、ProductID 1、2、および 3 をマッピング テーブルに挿入する必要があります。Europe Gaming Experience ショップでのコンソール (製品) の価格を次のように仮定します。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
この時点で、2 つのショップとその製品がマッピング テーブルにマップされました。では、これをすべてまとめて、Web サイトを閲覧しているユーザーを表示するにはどうすればよいでしょうか。European Gaming Experience のすべての製品を Web ページでユーザーに表示したいとします。次のクエリを実行する必要があります。
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
おそらく次の結果が表示されます。
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
最後の例として、あなたのウェブサイトにコンソールの最安値を見つける機能があるとしましょう。ユーザーが 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
このクエリは、XBOX360 を販売しているすべてのショップのリストを、最も安いショップから順に返します。
アジア競技大会のショップを追加していないことに気付くでしょう。演習として、次の製品を含むアジアのゲーム ショップをマッピング テーブルに追加します。Asian Games Emporium は、Wii ゲーム コンソールを 99.99 ドル、PS3 コンソールを 159.99 ドルで販売しています。この例に取り組むと、多対多の関係をモデル化する方法を理解できるはずです。
これが、データベース設計に関する旅行に役立つことを願っています。