Необходимо преобразовать функцию скалярного значения SQL с эквивалентом PATINDEX в VB
Долгое время читатель, первый постер. Извините заранее за стену текста.
Короткая версия: мне нужно знать, как использовать VB Instr (или какую-либо другую функцию VB) для поиска строки и возврата индекса первого вхождения любого из трех символов в этой строке. Любой из трех символов может появляться в строке любое количество раз в любом порядке. В Tsql я бы искал строку, используя PATINDEX
WHILE PATINDEX('%[#$@]%',@MyString) >0
где #,$ и @ - отдельные символы, которые мне нужно искать. Примечание: это замены - фактические символы, используемые "IRL", вызывают проблемы в моем сообщении stackOverflow.
Длинная версия: я написал функцию Tsql, которая принимает дату (дату начала гарантии), специальную строку с символами и числами из приложения и несколько других необходимых входных данных, а затем перебирает "специальную строку" и выполняет X-число операций DATEADD, в конечном итоге возвращая дату окончания гарантии. Проблема в том, что мне нужна эта дата для сообщения о хранилище БД и вызова функции для каждой строки, как будто это слишком медленно. Я хотел бы переместить всю функцию в задачу "Сценарий" в пакете служб SSIS, которая в первую очередь загружает данные, поэтому вычисление можно выполнить в памяти и сделать это нужно только один раз. Вот функция TSQL для ссылки:
CREATE FUNCTION [dbo].[CalcLDCoverageExp]
(
@LDCoverage int
,@LDCoveragePeriod varchar(max)
,@GracePeriod varchar(max)
,@dt datetime
,@WarrEndt datetime
)
RETURNS datetime
AS
BEGIN
Declare @code varchar(max), @symbol varchar(1),@val int
IF @LDCoverage=1
--There is LD coverage
BEGIN
IF LEN(rtrim(@LDCoveragePeriod))>0
--There is a Specific LDCoverage period on the Warrenty Agreement
BEGIN
SET @code=@LDCoveragePeriod+@GracePeriod
WHILE PATINDEX('%[#$@]%',@code) >0
BEGIN
SET @symbol=substring(@code,PATINDEX('%[#$@]%',@code),1)
SET @val= Left(@code,PATINDEX('%[#$@]%',@code)-1)
SET @dt = (Case @symbol When '#' Then DATEADD(YYYY,@val,@dt)
When '$' Then DATEADD(M,@val,@dt)
When '@' Then DATEADD(D,@val,@dt)
END)
SET @code = RIGHT(@code,Len(@code)-PATINDEX('%[#$@]%', @code))
--STUFF(@code, PATINDEX('%[#$@]%', @code), 1, '')
END
END
ELSE
--There is not a specific LDCoverage period on the Warrenty Agreement; LD=WarrentyEnd+1Day
SET @dt=Dateadd(d,1,@WarrEndt)
--END IF LEN(rtrim(@LDCoveragePeriod))>0
END
ELSE
--No LD Coverage
SET @dt=NULL
--END IF @LDCoverage=1
RETURN @dt
END
Я немного знаю VB.net и уверен, что, приложив немного усилий и потратив много времени на поиск в стеке, я смогу преобразовать оставшуюся часть функции TSQL в VB equlivalent. Но я застрял на том, как переписать это утверждение PATINDEX.
1 ответ
VB не имеет стандартной функции для получения индекса "первого вхождения любого из трех символов в этой строке". Вам придется создать что-то, что будет запускать instr() (или использовать новую версию.Net String.IndexOf
) 3 раза, чтобы получить наименьшее число. Не должно быть слишком сложно сделать.