Chế độ xem SQL - không có biến?


83

Có thể khai báo một biến trong Chế độ xem không? Ví dụ:

Declare @SomeVar varchar(8) = 'something'

cho tôi lỗi cú pháp:

Cú pháp không chính xác gần từ khóa 'Khai báo'.

Câu trả lời:


66

Bạn nói đúng. Biến cục bộ không được phép trong chế độ XEM.

Bạn có thể đặt một biến cục bộ trong một hàm có giá trị bảng, hàm này trả về một tập kết quả (giống như một dạng xem.)

http://msdn.microsoft.com/en-us/library/ms191165.aspx

ví dụ

CREATE FUNCTION dbo.udf_foo()
RETURNS @ret TABLE (col INT)
AS
BEGIN
  DECLARE @myvar INT;
  SELECT @myvar = 1;
  INSERT INTO @ret SELECT @myvar;
  RETURN;
END;
GO
SELECT * FROM dbo.udf_foo();
GO

Hiệu quả của nó có tương tự như một lượt xem không?
RaRdEvA

Không, TVF thường chậm hơn. "Các hàm có giá trị bảng (TVF) của SQL Server có vẻ là một ý tưởng hay, nhưng chúng che giấu một loạt các vấn đề về hiệu suất tiềm ẩn. và các TVF nhiều tuyên bố thậm chí có thể không có được sự tối ưu hóa tốt nhất. Tóm lại - TVF đã bốc mùi. " brentozar.com/blitzcache/tvf-join
wp78de

49

Bạn có thể sử dụng WITH để xác định các biểu thức của mình. Sau đó thực hiện một lệnh CHỌN phụ đơn giản để truy cập các định nghĩa đó.

CREATE VIEW MyView
AS
  WITH MyVars (SomeVar, Var2)
  AS (
    SELECT
      'something' AS 'SomeVar',
      123 AS 'Var2'
  )

  SELECT *
  FROM MyTable
  WHERE x = (SELECT SomeVar FROM MyVars)

3
đây là một hằng số, không phải một biến!
Vladislav

2
@Vladislav Nó có thể dễ dàng sử dụng dữ liệu (đã lọc?) Từ một bảng.
Dodecaphone

18

CHỈNH SỬA: Tôi đã thử sử dụng CTE cho câu trả lời trước đây của tôi, câu trả lời không chính xác, như được chỉ ra bởi @bummi. Tùy chọn này sẽ hoạt động thay thế:

Đây là một tùy chọn sử dụng ÁP DỤNG CHÉO, để giải quyết vấn đề này:

SELECT st.Value, Constants.CONSTANT_ONE, Constants.CONSTANT_TWO
FROM SomeTable st
CROSS APPLY (
    SELECT 'Value1' AS CONSTANT_ONE,
           'Value2' AS CONSTANT_TWO
) Constants

Cảm ơn bạn đã chỉnh sửa - đã cập nhật để thay vào đó sử dụng ÁP DỤNG CHÉO.
Daniel Neel

Điều này hoạt động, nhưng các cột của Áp dụng chéo không được khởi động lại cho mọi hàng? Đặc biệt là đối với các giá trị được tính toán có nghĩa là sẽ mất hiệu suất lớn. Chỉ đáng buồn là Biến cục bộ và CTE không có sẵn trong Chế độ xem, có ai biết tại sao không?
T_D

1
@T_D bạn có thể tạo và sử dụng 'CTE' trong 'Chế độ xem'.
Có thể bán được

6

@datenstation đã có khái niệm chính xác. Đây là một ví dụ hoạt động sử dụng CTE để lưu tên biến vào bộ nhớ cache:

CREATE VIEW vwImportant_Users AS
WITH params AS (
    SELECT 
    varType='%Admin%', 
    varMinStatus=1)
SELECT status, name 
    FROM sys.sysusers, params
    WHERE status > varMinStatus OR name LIKE varType

SELECT * FROM vwImportant_Users

cũng thông qua JOIN

WITH params AS ( SELECT varType='%Admin%', varMinStatus=1)
SELECT status, name 
    FROM sys.sysusers INNER JOIN params ON 1=1
    WHERE status > varMinStatus OR name LIKE varType

cũng thông qua CROSS APPLY

WITH params AS ( SELECT varType='%Admin%', varMinStatus=1)
SELECT status, name 
    FROM sys.sysusers CROSS APPLY params
    WHERE status > varMinStatus OR name LIKE varType

4

Sử dụng các hàm như spencer7593 đã đề cập là một cách tiếp cận đúng cho dữ liệu động. Đối với dữ liệu tĩnh, một cách tiếp cận hiệu quả hơn phù hợp với thiết kế dữ liệu SQL (so với kiểu chống lại việc ghi mã thủ tục lớn trong các lớp) là tạo một bảng riêng biệt với các giá trị tĩnh và kết hợp với nó. Điều này cực kỳ có lợi từ góc độ hiệu suất vì SQL Engine có thể xây dựng các kế hoạch thực thi hiệu quả xung quanh một JOIN và bạn cũng có khả năng thêm các chỉ mục nếu cần.

Nhược điểm của việc sử dụng các hàm (hoặc bất kỳ giá trị được tính toán nội tuyến nào) là chú thích xảy ra cho mọi hàng tiềm năng được trả về, điều này gây tốn kém. Tại sao? Bởi vì SQL trước tiên phải tạo một tập dữ liệu đầy đủ với các giá trị được tính toán và sau đó áp dụng mệnh đề WHERE cho tập dữ liệu đó.

Chín lần trong số mười lần bạn không cần các giá trị ô được tính toán động trong các truy vấn của mình. Tốt hơn nhiều là tìm ra những gì bạn sẽ cần, sau đó thiết kế một mô hình dữ liệu hỗ trợ nó và điền vào mô hình dữ liệu đó với dữ liệu bán động (ví dụ: thông qua các công việc hàng loạt) và sử dụng SQL Engine để thực hiện công việc nặng nhọc thông qua SQL tiêu chuẩn .


3

Đúng, điều này đúng, bạn không thể có các biến trong chế độ xem (cũng có những hạn chế khác).

Các khung nhìn có thể được sử dụng cho các trường hợp có thể thay thế kết quả bằng một câu lệnh select.


Một hàm bảng có thể được thay thế trong một câu lệnh select và nó có các biến cục bộ.
JeffO

Bạn đang nói vì một câu lệnh select không thể có các biến cục bộ, một chế độ xem cũng không thể?
JeffO

1
@JeffO "bạn không thể có các biến trong lượt xem" là những gì tôi đã nói. Điều này không rõ ràng?
Hogan

Đó là câu cuối cùng. Một khung nhìn có thể thay thế một câu lệnh select nhưng điều đó liên quan gì đến các biến? Một hàm bảng không thể thay thế một câu lệnh select, nhưng bao gồm các biến?
JeffO

1
Một hàm bảng cũng có thể được thay thế bằng một câu lệnh select, nhưng không thể sử dụng các hàm bảng ở mọi nơi mà một dạng xem có thể, chẳng hạn như các phép nối. Những gì anh ta đang cố gắng nói là một dạng xem có thể thay thế một câu lệnh select duy nhất, nhưng không thể thay thế nhiều câu lệnh. Từ khóa BEGIN không hợp lệ trong câu lệnh CREATE VIEW, cũng như hàm nội tuyến. Nó sẽ là cần thiết để tạo một tập lệnh đa câu. Thủ tục hoặc nhiều hàm câu lệnh có lẽ là cách tốt nhất để làm điều này.
Arlen Beiler

1

Những gì tôi làm là tạo một dạng xem thực hiện việc chọn giống như biến bảng và liên kết dạng xem đó với dạng xem thứ hai. Vì vậy, một chế độ xem có thể chọn từ một chế độ xem khác. Điều này đạt được kết quả tương tự


2
Ben, điều này có thể gây ra sự cố về hiệu suất trừ khi bạn đang xử lý các bảng rất nhỏ.
logixologist

Ngay cả với bảng rất nhỏ (3 bản ghi), một Chế độ xem với hàng triệu bản ghi gây ra các vấn đề lớn về hiệu suất.
st_stefanov

0

Bạn cần làm mới chế độ xem bao lâu một lần? Tôi gặp trường hợp tương tự khi dữ liệu mới đến mỗi tháng một lần; sau đó tôi phải tải nó và trong quá trình tải, tôi phải tạo các bảng mới. Vào lúc đó, tôi thay đổi quan điểm của mình để xem xét các thay đổi. Tôi đã sử dụng thông tin cơ bản trong câu hỏi khác này:

Tạo Chế độ xem Động & từ đồng nghĩa

Trong đó, đề xuất thực hiện theo 2 cách:

  1. sử dụng từ đồng nghĩa.
  2. Sử dụng SQL động để tạo chế độ xem (đây là điều đã giúp tôi đạt được kết quả của mình).
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.