Tôi biết điều này là rất muộn, nhưng tôi đã có một tình huống tương tự. Tôi cần một toán tử "Thích trong" cho một tập hợp các thủ tục được lưu trữ mà tôi có, chấp nhận nhiều tham số và sau đó sử dụng các tham số đó để tổng hợp dữ liệu từ nhiều hệ thống RDBMS, do đó không có thủ thuật cụ thể nào của RDBMS hoạt động, tuy nhiên thủ tục được lưu trữ và bất kỳ chức năng nào sẽ chạy trên MS SQL Server, vì vậy chúng tôi có thể sử dụng T-SQL cho chức năng tạo các câu lệnh SQL đầy đủ cho mỗi RDBMS, nhưng đầu ra cần phải độc lập với RDBMS.
Đây là những gì tôi nghĩ ra lúc này để biến một chuỗi được phân tách (chẳng hạn như một tham số đi vào một thủ tục được lưu trữ) thành một khối SQL. Tôi gọi nó là "Địa y" cho "THÍCH VÀO". Hiểu rồi?
Địa y
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =======================================================================
-- Lichen - Scalar Valued Function
-- Returns nvarchar(512) of "LIKE IN" results. See further documentation.
-- CREATOR: Norman David Cooke
-- CREATED: 2020-02-05
-- UPDATED:
-- =======================================================================
CREATE OR ALTER FUNCTION Lichen
(
-- Add the parameters for the function here
@leadingAnd bit = 1,
@delimiter nchar(1) = ';',
@colIdentifier nvarchar(64),
@argString nvarchar(256)
)
RETURNS nvarchar(512)
AS
BEGIN
-- Declare the return variable here
DECLARE @result nvarchar(512)
-- set delimiter to detect (add more here to detect a delimiter if one isn't provided)
DECLARE @delimit nchar(1) = ';'
IF NOT @delimiter = @delimit
SET @delimit = @delimiter
-- check to see if we have any delimiters in the input pattern
IF CHARINDEX(@delimit, @argString) > 1 -- check for the like in delimiter
BEGIN -- begin 'like in' branch having found a delimiter
-- set up a table variable and string_split the provided pattern into it.
DECLARE @lichenTable TABLE ([id] [int] IDENTITY(1,1) NOT NULL, line NVARCHAR(32))
INSERT INTO @lichenTable SELECT * FROM STRING_SPLIT(@argString, ';')
-- setup loop iterators and determine how many rows were inserted into lichen table
DECLARE @loopCount int = 1
DECLARE @lineCount int
SELECT @lineCount = COUNT(*) from @lichenTable
-- select the temp table (to see whats inside for debug)
--select * from @lichenTable
-- BEGIN AND wrapper block for 'LIKE IN' if bit is set
IF @leadingAnd = 1
SET @result = ' AND ('
ELSE
SET @result = ' ('
-- loop through temp table to build multiple "LIKE 'x' OR" blocks inside the outer AND wrapper block
WHILE ((@loopCount IS NOT NULL) AND (@loopCount <= @lineCount))
BEGIN -- begin loop through @lichenTable
IF (@loopcount = 1) -- the first loop does not get the OR in front
SELECT @result = CONCAT(@result, ' ', @colIdentifier, ' LIKE ''', line, '''') FROM @lichenTable WHERE id = @loopCount
ELSE -- but all subsequent loops do
SELECT @result = CONCAT(@result, ' OR ', @colIdentifier, ' LIKE ''', line, '''') FROM @lichenTable WHERE id = @loopCount
SET @loopcount = @loopCount + 1 -- increment loop
END -- end loop through @lichenTable
-- set final parens after lichenTable loop
SET @result = CONCAT(@result, ' )')
END -- end 'like in' branch having found a delimiter
ELSE -- no delimiter was provided
BEGIN -- begin "no delimiter found" branch
IF @leadingAnd = 1
SET @result = CONCAT(' AND ', @colIdentifier, ' LIKE ''' + @argString + '''')
ELSE
SET @result = CONCAT(' ', @colIdentifier, ' LIKE ''' + @argString + '''')
END -- end "no delimiter found" branch
-- Return the result of the function
RETURN @result
END -- end lichen function
GO
Việc phát hiện dấu phân cách có thể được lên kế hoạch, nhưng bây giờ nó mặc định là dấu chấm phẩy để bạn có thể đặt default
vào đó. Có lẽ có lỗi trong này. Các @leadingAnd
thông số chỉ là một giá trị bit để xác định xem bạn muốn có một "VÀ" đặt hàng đầu ở phía trước của khối sao cho nó vừa độc đáo với mệnh đề WHERE bổ sung khác.
Sử dụng ví dụ (với dấu phân cách trong argString)
SELECT [dbo].[Lichen] (
default -- @leadingAND, bit, default: 1
,default -- @delimiter, nchar(1), default: ';'
,'foo.bar' -- @colIdentifier, nvarchar(64), this is the column identifier
,'01%;02%;%03%' -- @argString, nvarchar(256), this is the input string to parse "LIKE IN" from
)
GO
Sẽ trả về một nvarchar (512) có chứa:
AND ( foo.bar LIKE '01%' OR foo.bar LIKE '02%' OR foo.bar LIKE '%03%' )
Nó cũng sẽ bỏ qua khối nếu đầu vào không chứa dấu phân cách:
Sử dụng ví dụ (không có dấu phân cách trong argString)
SELECT [dbo].[Lichen] (
default -- @leadingAND, bit, default: 1
,default -- @delimiter, nchar(1), default: ';'
,'foo.bar' -- @colIdentifier, nvarchar(64), this is the column identifier
,'01%' -- @argString, nvarchar(256), this is the input string to parse "LIKE IN" from
)
GO
Sẽ trả về một nvarchar (512) có chứa:
AND foo.bar LIKE '01%'
Tôi sẽ tiếp tục làm việc này, vì vậy nếu tôi bỏ qua điều gì đó (rõ ràng là rõ ràng hoặc nói cách khác) xin vui lòng bình luận hoặc tiếp cận.