26

tôi có chức năng người dùng định nghĩa sau đây:Sql Server xác định người dùng định nghĩa chức năng

create function [dbo].[FullNameLastFirst] 
(
    @IsPerson bit, 
    @LastName nvarchar(100), 
    @FirstName nvarchar(100) 
) 
returns nvarchar(201) 
as 
begin 
    declare @Result nvarchar(201) 
    set @Result = (case when @IsPerson = 0 then @LastName else case when @FirstName = '' then @LastName else (@LastName + ' ' + @FirstName) end end) 
    return @Result 
end 

Tôi không thể tạo ra một chỉ số trên một cột tính sử dụng chức năng này vì nó là không xác định. Ai đó có thể giải thích tại sao nó không xác định và cuối cùng làm thế nào để sửa đổi để làm cho nó xác định? Cảm ơn

Trả lời

40

Bạn chỉ cần tạo nó with schemabinding.

Máy chủ SQL sau đó sẽ xác minh xem nó có đáp ứng các tiêu chí được coi là xác định hay không (mà nó không truy cập bất kỳ bảng bên ngoài hoặc sử dụng các hàm không xác định như getdate()).

Bạn có thể xác nhận rằng nó làm việc với

SELECT OBJECTPROPERTY(OBJECT_ID('[dbo].[FullNameLastFirst]'), 'IsDeterministic') 

Thêm tùy chọn schemabinding mã ban đầu của bạn hoạt động tốt nhưng một phiên bản hơi đơn giản sẽ là.

CREATE FUNCTION [dbo].[FullNameLastFirst] (@IsPerson BIT, 
              @LastName NVARCHAR(100), 
              @FirstName NVARCHAR(100)) 
RETURNS NVARCHAR(201) 
WITH SCHEMABINDING 
AS 
    BEGIN 
     RETURN CASE 
       WHEN @IsPerson = 0 
        OR @FirstName = '' THEN @LastName 
       ELSE @LastName + ' ' + @FirstName 
      END 
    END 
+1

Tôi tạo ra Index của tôi chỉ vào cột tính. Tôi cũng có Chế độ xem đề cập đến bảng của tôi. Tôi nghĩ rằng tôi phải chỉ định SchemaBinding trên View để tạo một Index trên cùng một cột. Về điều này, nếu Bảng cơ sở của tôi như là một chỉ số trên cột được tính toán, là dư thừa tạo ra một chỉ số trên View? – opaera

+0

@opaera - Có - Bạn cũng sẽ không cần lập chỉ mục cột đó trong chế độ xem. –

+0

Câu hỏi cuối cùng, nếu bạn có thể. Tôi có một sp mà làm cho một truy vấn trên View (View xem tham chiếu bảng được lập chỉ mục của tôi). Tôi có thể/nên chỉ định tên Index vào truy vấn từ mệnh đề? ví dụ. Chọn * Từ MyView (Với MyTableIndex) ... Có lẽ tôi có một số lợi ích khi làm điều đó? – opaera

4

Bạn cần phải khai báo User Defined Function với SchemaBinding

create function [dbo].[FullNameLastFirst] 
( 
    @IsPerson bit, 
    @LastName nvarchar(100), 
    @FirstName nvarchar(100) 
) 
returns nvarchar(201) 
with schemabinding 
as 
begin 
    declare @Result nvarchar(201) 
    set @Result = (case when @IsPerson = 0 then @LastName else case when @FirstName = '' then @LastName else (@LastName + ' ' + @FirstName) end end) 
    return @Result 
end 


create table Person 
(
isperson bit, 
lastname nvarchar(100), 
firstname nvarchar(100), 
fullname as [dbo].[FullNameLastFirst] (isperson, lastname, firstname) 
) 
go 
insert into person(isperson, lastname, firstname) values (1,'Firstname', 'Surname') 
go 

create index ix1_person on person(fullname) 
go 

select fullname from Person with (index=ix1_person) where fullname = 'Firstname Surname' 
go 
Các vấn đề liên quan