sql >> Databáze >  >> RDS >> Sqlserver

T-SQL Jak dynamicky vytvářet tabulky v uložených procedurách?

Používáte proměnnou tabulky, tj. měli byste deklarovat tabulku. Toto není dočasná tabulka.

Dočasnou tabulku vytvoříte takto:

CREATE TABLE #customer
(
     Name varchar(32) not null
)

Proměnnou tabulky deklarujete takto:

DECLARE @Customer TABLE
(
      Name varchar(32) not null
)

Všimněte si, že dočasná tabulka je deklarována pomocí # a proměnná tabulky je deklarována pomocí @.Přečtěte si o rozdílu mezi proměnnými tabulky a dočasnými tabulkami.

AKTUALIZACE:

Na základě vašeho komentáře níže se ve skutečnosti pokoušíte vytvořit tabulky v uložené proceduře. K tomu budete muset použít dynamické SQL. V zásadě dynamické SQL vám umožňuje sestavit příkaz SQL ve formě řetězce a poté jej spustit. Toto je JEDINÝ způsob, jak budete moci vytvořit tabulku v uložené proceduře. Ukážu vám, jak na to, a poté diskutuji o tom, proč to obecně není dobrý nápad.

Nyní jednoduchý příklad (tento kód jsem netestoval, ale měl by vám dobře naznačit, jak to udělat):

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 '[email protected] + '( '[email protected]+' '[email protected] +' '[email protected] +') ON PRIMARY '

   EXEC (@SQLString)
   GO

Tato uložená procedura může být provedena takto:

sproc_BuildTable 'Customers','CustomerName','VARCHAR(32)','NOT NULL'

S tímto typem uložené procedury jsou některé velké problémy.

Bude obtížné obsloužit složité tabulky. Představte si následující strukturu tabulky:

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 

Tato tabulka je o něco složitější než první příklad, ale ne o moc. Uložená procedura bude mnohem, mnohem složitější. Takže i když tento přístup může fungovat pro malé tabulky, rychle se stane neřiditelným.

Vytváření tabulek vyžaduje plánování. Když vytváříte tabulky, měly by být strategicky umístěny do různých skupin souborů. Tím se zajistí, že nezpůsobíte spory o vstup/výstup disku. Jak budete řešit škálovatelnost, pokud je vše vytvořeno v primární skupině souborů?

Mohl byste objasnit, proč potřebujete, aby byly tabulky vytvářeny dynamicky?

AKTUALIZACE 2:

Zpožděná aktualizace kvůli pracovnímu vytížení. Četl jsem váš komentář o potřebě vytvořit tabulku pro každý obchod a myslím, že byste to měli udělat jako příklad, který vám dám.

V tomto příkladu vycházím z následujících předpokladů:

  1. Je to stránka elektronického obchodu, která má mnoho obchodů
  2. Obchod může mít k prodeji mnoho položek (zboží).
  3. Konkrétní položku (zboží) lze prodat v mnoha obchodech
  4. Obchod bude účtovat různé ceny za různé položky (zboží)
  5. Všechny ceny jsou v USD (USD)

Řekněme, že tento web elektronického obchodu prodává herní konzole (tj. Wii, PS3, XBOX360).

Když se podívám na své předpoklady, vidím klasický vztah mnoho k mnoha. Obchod může prodávat mnoho položek (zboží) a položky (zboží) lze prodávat v mnoha obchodech. Pojďme si to rozdělit do tabulek.

Nejprve bych potřeboval tabulku obchodu, na kterou bych uložil všechny informace o obchodě.

Jednoduchý obchodní stůl může vypadat takto:

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

Vložme do databáze tři obchody, které použijeme v našem příkladu. Následující kód vloží tři obchody:

INSERT INTO Shop
SELECT 'American Games R US'
UNION
SELECT 'Europe Gaming Experience'
UNION
SELECT 'Asian Games Emporium'

Pokud spustíte SELECT * FROM Shop pravděpodobně uvidíte následující:

ShopID  ShopName
1           American Games R US
2           Asian Games Emporium
3           Europe Gaming Experience

Dobře, takže nyní přejdeme k tabulce Položky (zboží). Vzhledem k tomu, že položky/zboží jsou produkty různých společností, budu nazývat stolní produkt. Pro vytvoření jednoduché tabulky produktů můžete spustit následující kód.

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

Pojďme naplnit tabulku produktů některými produkty. Pro vložení některých produktů spusťte následující kód:

INSERT INTO Product
SELECT 'Wii'
UNION 
SELECT 'PS3'
UNION 
SELECT 'XBOX360'

Pokud spustíte SELECT * FROM Product pravděpodobně uvidíte následující:

ProductID   ProductDescription
1           PS3
2           Wii
3           XBOX360

OK, v tomto okamžiku máte informace o produktu i obchodu. Jak je tedy dát dohromady? Dobře víme, že můžeme identifikovat obchod podle sloupce primárního klíče ShopID a víme, že můžeme identifikovat produkt podle sloupce primárního klíče ProductID. Vzhledem k tomu, že každý obchod má pro každý produkt jinou cenu, musíme také uložit cenu, kterou obchod za produkt účtuje.

Máme tedy tabulku, která mapuje obchod k produktu. Tuto tabulku budeme nazývat ShopProduct. Jednoduchá verze této tabulky může vypadat takto:

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

Předpokládejme tedy, že obchod American Games R Us prodává pouze americké konzole, Europe Gaming Experience prodává všechny konzole a Asian Games Emporium prodává pouze asijské konzole. Potřebovali bychom namapovat primární klíče z tabulek obchodu a produktů do tabulky ShopProduct.

Zde je návod, jak provedeme mapování. V mém příkladu má American Games R Us hodnotu ShopID 1 (toto je hodnota primárního klíče) a vidím, že XBOX360 má hodnotu 3 a obchod uvedl XBOX360 za 159,99 $

Spuštěním následujícího kódu dokončíte mapování:

INSERT INTO ShopProduct VALUES(1,3,159.99)

Nyní chceme přidat všechny produkty do obchodu Europe Gaming Experience. V tomto příkladu víme, že obchod Europe Gaming Experience má ShopID 3 a protože prodává všechny konzole, budeme muset vložit ProductID 1, 2 a 3 do mapovací tabulky. Předpokládejme, že ceny konzolí (produktů) v obchodě Europe Gaming Experience jsou následující:1- PS3 se prodává za 259,99 USD, 2- Wii se prodává za 159,99 USD, 3- XBOX360 se prodává za 199,99 USD.

Chcete-li provést toto mapování, budete muset provést následující kód:

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

V tomto okamžiku jste zmapovali dva obchody a jejich produkty do mapovací tabulky. OK, takže jak to teď dám dohromady, aby se uživateli zobrazilo procházení webu? Řekněme, že chcete uživateli na webové stránce ukázat veškerý produkt pro European Gaming Experience – museli byste provést následující dotaz:

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

Pravděpodobně uvidíte následující výsledky:

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

Nyní poslední příklad, předpokládejme, že váš web má funkci, která najde nejnižší cenu konzole. Uživatel požádá o nalezení nejlevnějších cen pro XBOX360.

Můžete provést následující dotaz:

 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

Tento dotaz vrátí seznam všech obchodů, které prodávají XBOX360 s nejlevnějším obchodem jako první a tak dále.

Všimnete si, že jsem nepřidal obchod s asijskými hrami. Pro cvičení přidejte obchod s asijskými hrami do mapovacího stolu s následujícími produkty:Asian Games Emporium prodává herní konzoli Wii za 99,99 USD a konzoli PS3 za 159,99 USD. Pokud projdete tímto příkladem, měli byste nyní porozumět tomu, jak modelovat vztah mnoho k mnoha.

Doufám, že vám to pomůže na cestách s návrhem databáze.



  1. Jak mohu v Oracle zkombinovat více řádků do seznamu odděleného čárkami?

  2. Příklady SQRT() v SQL Server

  3. Upozornění:Nelze upravit informace v záhlaví - záhlaví již byla odeslána omylem

  4. Datový model agentury pro veřejné mínění