Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

T-SQL Làm thế nào để tạo bảng động trong các thủ tục được lưu trữ?

Bạn đang sử dụng một biến bảng tức là bạn nên khai báo bảng. Đây không phải là một bảng tạm thời.

Bạn tạo một bảng tạm thời như vậy:

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

Bạn khai báo một biến bảng như sau:

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

Lưu ý rằng một bảng tạm thời được khai báo bằng cách sử dụng # và một biến bảng được khai báo bằng cách sử dụng @ .Go đọc về sự khác biệt giữa các biến bảng và bảng tạm thời.

CẬP NHẬT:

Dựa trên nhận xét của bạn dưới đây, bạn thực sự đang cố gắng tạo bảng trong một quy trình được lưu trữ. Đối với điều này, bạn sẽ cần sử dụng SQL động. Về cơ bản, SQL động cho phép bạn xây dựng Câu lệnh SQL dưới dạng một chuỗi và sau đó thực thi nó. Đây là cách DUY NHẤT bạn có thể tạo một bảng trong một thủ tục được lưu trữ. Tôi sẽ chỉ cho bạn cách thực hiện và sau đó thảo luận về lý do tại sao nói chung đây không phải là một ý kiến ​​hay.

Bây giờ là một ví dụ đơn giản (tôi chưa thử nghiệm mã này nhưng nó sẽ cung cấp cho bạn một chỉ dẫn tốt về cách thực hiện):

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

Thủ tục được lưu trữ này có thể được thực thi như sau:

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

Có một số vấn đề lớn với loại thủ tục được lưu trữ này.

Nó sẽ khó đáp ứng cho các bảng phức tạp. Hãy tưởng tượng cấu trúc bảng sau:

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 

Bảng này phức tạp hơn một chút so với ví dụ đầu tiên, nhưng không nhiều. Thủ tục được lưu trữ sẽ phức tạp hơn rất nhiều để giải quyết. Vì vậy, mặc dù cách tiếp cận này có thể hoạt động đối với các bảng nhỏ nhưng sẽ nhanh chóng không thể quản lý được.

Tạo bảng yêu cầu lập kế hoạch. Khi bạn tạo bảng, chúng nên được đặt một cách chiến lược trên các nhóm tệp khác nhau. Điều này là để đảm bảo rằng bạn không gây ra tranh chấp I / O đĩa. Bạn sẽ giải quyết khả năng mở rộng như thế nào nếu mọi thứ được tạo trên nhóm tệp chính?

Bạn có thể giải thích lý do tại sao bạn cần các bảng được tạo động không?

CẬP NHẬT 2:

Cập nhật bị trì hoãn do khối lượng công việc. Tôi đã đọc nhận xét của bạn về việc cần tạo bàn cho mỗi cửa hàng và tôi nghĩ bạn nên xem xét cách làm đó giống như ví dụ mà tôi sắp đưa ra cho bạn.

Trong ví dụ này, tôi đưa ra các giả định sau:

  1. Đây là một trang web thương mại điện tử có nhiều cửa hàng
  2. Một cửa hàng có thể có nhiều mặt hàng (hàng hoá) để bán.
  3. Một mặt hàng cụ thể (tốt) có thể được bán ở nhiều cửa hàng
  4. Một cửa hàng sẽ tính các mức giá khác nhau cho các mặt hàng (hàng hóa) khác nhau
  5. Tất cả giá đều tính bằng $ (USD)

Giả sử trang thương mại điện tử này bán máy chơi game (tức là Wii, PS3, XBOX360).

Nhìn vào các giả định của tôi, tôi thấy một mối quan hệ nhiều-nhiều cổ điển. Một cửa hàng có thể bán nhiều vật phẩm (hàng hoá) và vật phẩm (hàng hoá) có thể bán ở nhiều cửa hàng. Hãy chia điều này thành các bảng.

Đầu tiên, tôi cần một bảng cửa hàng để lưu trữ tất cả thông tin về cửa hàng.

Một bảng cửa hàng đơn giản có thể trông như thế này:

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

Hãy chèn ba cửa hàng vào cơ sở dữ liệu để sử dụng trong ví dụ của chúng tôi. Đoạn mã sau sẽ chèn ba cửa hàng:

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

Nếu bạn thực hiện SELECT * FROM Shop bạn có thể sẽ thấy những điều sau:

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

Đúng vậy, bây giờ chúng ta hãy chuyển sang bảng Vật phẩm (hàng hóa). Vì các mặt hàng / hàng hóa là sản phẩm của nhiều công ty khác nhau nên tôi sẽ gọi là sản phẩm bảng. Bạn có thể thực thi mã sau để tạo một bảng Sản phẩm đơn giản.

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

Hãy điền vào bảng sản phẩm với một số sản phẩm. Thực thi đoạn mã sau để chèn một số sản phẩm:

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

Nếu bạn thực thi SELECT * FROM Product bạn có thể sẽ thấy những điều sau:

ProductID   ProductDescription
1           PS3
2           Wii
3           XBOX360

OK, lúc này bạn đã có cả thông tin sản phẩm và cửa hàng. Vì vậy, làm thế nào để bạn mang chúng lại với nhau? Chúng tôi biết rằng chúng tôi có thể xác định cửa hàng bằng cột khóa chính ShopID của nó và chúng tôi biết chúng tôi có thể xác định một sản phẩm bằng cột khóa chính ProductID của nó. Ngoài ra, vì mỗi cửa hàng có một mức giá khác nhau cho mỗi sản phẩm nên chúng tôi cần lưu trữ giá mà cửa hàng tính cho sản phẩm đó.

Vì vậy, chúng tôi có một bảng ánh xạ Shop với sản phẩm. Chúng tôi sẽ gọi bảng này là ShopProduct. Một phiên bản đơn giản của bảng này có thể trông giống như sau:

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

Vì vậy, giả sử cửa hàng American Games R Us chỉ bán bảng điều khiển của Mỹ, Europe Gaming Experience bán tất cả bảng điều khiển và Asian Games Emporium chỉ bán bảng điều khiển của châu Á. Chúng tôi cần ánh xạ các khóa chính từ cửa hàng và bảng sản phẩm vào bảng ShopProduct.

Đây là cách chúng ta sẽ lập bản đồ. Trong ví dụ của tôi, American Games R Us có giá trị ShopID là 1 (đây là giá trị khóa chính) và tôi có thể thấy rằng XBOX360 có giá trị là 3 và cửa hàng đã niêm yết XBOX360 với giá $ 159,99

Bằng cách thực thi đoạn mã sau, bạn sẽ hoàn thành việc ánh xạ:

INSERT INTO ShopProduct VALUES(1,3,159.99)

Bây giờ chúng tôi muốn thêm tất cả sản phẩm vào cửa hàng Trải nghiệm chơi game Châu Âu. Trong ví dụ này, chúng tôi biết rằng cửa hàng Trải nghiệm Trò chơi Châu Âu có ShopID là 3 và vì cửa hàng này bán tất cả các bảng điều khiển nên chúng tôi sẽ cần chèn ProductID 1, 2 và 3 vào bảng ánh xạ. Giả sử giá của các bảng điều khiển (sản phẩm) tại cửa hàng Europe Gaming Experience như sau:1- PS3 được bán với giá $ 259,99, 2- Wii được bán với giá $ 159,99, 3- XBOX360 được bán với giá $ 199,99.

Để thực hiện ánh xạ này, bạn cần thực thi đoạn mã sau:

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

Tại thời điểm này, bạn đã ánh xạ hai cửa hàng và sản phẩm của họ vào bảng ánh xạ. OK, vậy bây giờ làm cách nào để kết hợp tất cả những điều này lại với nhau để hiển thị một người dùng đang duyệt trang web? Giả sử bạn muốn hiển thị tất cả sản phẩm dành cho Trải nghiệm chơi game Châu Âu cho người dùng trên trang web - bạn cần thực hiện truy vấn sau:

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

Bạn có thể sẽ thấy các kết quả sau:

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

Bây giờ đối với một ví dụ cuối cùng, hãy giả sử rằng trang web của bạn có một tính năng tìm giá rẻ nhất cho một bảng điều khiển. Một người dùng yêu cầu tìm giá rẻ nhất cho XBOX360.

Bạn có thể thực hiện truy vấn sau:

 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

Truy vấn này sẽ trả về danh sách tất cả các cửa hàng bán XBOX360 với cửa hàng rẻ nhất trước tiên, v.v.

Bạn sẽ nhận thấy rằng tôi chưa thêm cửa hàng Asian Games. Như một bài tập, hãy thêm cửa hàng trò chơi châu Á vào bảng lập bản đồ với các sản phẩm sau:Asian Games Emporium bán bảng điều khiển trò chơi Wii với giá 99,99 đô la và bảng điều khiển PS3 với giá 159,99 đô la. Nếu bạn làm việc thông qua ví dụ này, bây giờ bạn sẽ hiểu cách mô hình mối quan hệ nhiều-nhiều.

Tôi hy vọng điều này sẽ giúp bạn trong chuyến đi của bạn với thiết kế cơ sở dữ liệu.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Lỗi 28000:Đăng nhập không thành công cho người dùng DOMAIN \\ người dùng với pyodbc

  2. Điều chỉnh dịch vụ báo cáo máy chủ SQL

  3. SQL Server datetime LIKE chọn?

  4. Xóa số khỏi máy chủ sql chuỗi

  5. Cách nối các chuỗi trong SQL Server với CONCAT ()