টি-এসকিউএল ব্যবহার করে একটি উপ-স্ট্রিংয়ের শেষ ঘটনার সূচকটি সন্ধান করুন


127

এসকিউএল ব্যবহার করে কোনও স্ট্রিংয়ের শেষ ঘটনাটির সূচকটি খুঁজে পাওয়ার কোনও সহজ উপায় আছে? আমি এখনই এসকিউএল সার্ভার 2000 ব্যবহার করছি। আমার কাছে মূলত। নেট System.String.LastIndexOfপদ্ধতি সরবরাহ করে এমন কার্যকারিতা দরকার । একটি সামান্য গুগলিং এটি প্রকাশ করেছে - শেষ সূচকটি পুনরুদ্ধার করতে ফাংশন - তবে আপনি "পাঠ্য" কলামের এক্সপ্রেশনটি পাস করলে তা কার্যকর হয় না। আপনি যে পাঠ্যের সন্ধান করছেন এটি 1 অক্ষর দীর্ঘ হিসাবে অন্য কোথাও পাওয়া অন্য সমাধানগুলি এতক্ষণ কাজ করে।

আমি সম্ভবত একটি ফাংশন আপ রান্না করতে হবে। যদি আমি এটি করি তবে আমি এটি এখানে পোস্ট করব যাতে আপনি লোকেরা এটি দেখতে পারেন এবং সম্ভবত এটি ব্যবহার করতে পারেন।

উত্তর:


33

আপনি পাঠ্য ডেটা টাইপের জন্য ফাংশনগুলির ছোট তালিকার মধ্যে সীমাবদ্ধ ।

আমি যে সমস্ত পরামর্শ দিতে পারি তা দিয়ে শুরু করা হয় PATINDEX, তবে DATALENGTH-1, DATALENGTH-2, DATALENGTH-3আপনি ফলাফল না পাওয়া বা শূন্যের শেষ না হওয়া অবধি ইত্যাদি থেকে পিছনের দিকে কাজ করুন (ডেটালএনজিটিএইচটি-ডাটাবেইজটি)

এটি সত্যিই এমন কিছু যা SQL Server 2000সহজভাবে পরিচালনা করতে পারে না।

অন্যান্য উত্তরের জন্য সম্পাদনা করুন : এসকিউএল সার্ভার 2000-এ টেক্সট ডেটা সহ ব্যবহার করা যেতে পারে এমন ফাংশনগুলির তালিকায় রেভারস নেই


1
হ্যাঁ, এটি বেশ বিশ্রী। এটি সাধারণ হওয়া উচিত বলে মনে হচ্ছে, কেবল তা নয়!
রাজ

... এই কারণেই এসকিউএল 2005-এ স্বাভাবিক ক্রিয়াকলাপের অনুমতি দিতে
ভারচার

1
আহ! সুতরাং "বর্ণচর (সর্বাধিক)" একটি এসকিউএল 2005 জিনিস, যা এসকিউএল 2000 এ চেষ্টা করার পরে এটি কেন কাজ করে না তা ব্যাখ্যা করে
রাজ

LENGTH কাজ করলেও ডেটালেগটিথ আমার জন্য সঠিক ফলাফল দিতে ব্যর্থ।
টকিলা

@ টেকিলা এবং অন্যান্য: DATALENGTHঅক্ষর নয়, বাইট সংখ্যা প্রদান করে। অতএব, DATALENGTHআয় 2 জন্য একটি স্ট্রিং x অক্ষরের সংখ্যা NVARCHARস্ট্রিং। LENযাইহোক, অক্ষরের সংখ্যা প্রদান করে, কোনও পিছনের সাদা স্থানকে বিয়োগ করবে । আমি কখনোই ব্যবহার DATALENGTHচরিত্র দৈর্ঘ্য গণনায় যদি না trailing হোয়াইটস্পেস গুরুত্বপূর্ণ এবং আমি নিশ্চিত যে আমার datatypes সামঞ্জস্যপূর্ণ হয়, কিনা তারা হতে জানি VARCHARবাNVARCHAR
rbsdca

174

সোজা পথ? না, তবে আমি বিপরীতটি ব্যবহার করেছি। আক্ষরিক।

পূর্বের রুটিনগুলিতে, প্রদত্ত স্ট্রিংয়ের শেষ উপস্থিতিটি সন্ধান করার জন্য, আমি রিভার্স () ফাংশনটি ব্যবহার করেছি, CHARINDEX অনুসরণ করেছি, তারপরে পুনরায় মূল ক্রম পুনরুদ্ধার করার জন্য REVERSE অনুসরণ করব। এই ক্ষেত্রে:

SELECT
   mf.name
  ,mf.physical_name
  ,reverse(left(reverse(physical_name), charindex('\', reverse(physical_name)) -1))
 from sys.master_files mf

সাবফোল্ডারগুলিতে যত গভীরভাবে বাসা বাঁধে না কেন, কীভাবে প্রকৃত ডাটাবেস ফাইলের নামগুলি তাদের "শারীরিক নাম" থেকে বের করা যায় তা দেখায়। এটি কেবলমাত্র একটি অক্ষর (ব্যাকস্ল্যাশ) অনুসন্ধান করে তবে আপনি দীর্ঘতর অনুসন্ধানের স্ট্রিংয়ের জন্য এটি তৈরি করতে পারেন।

কেবলমাত্র নেতিবাচক দিকটি হ'ল, আমি জানি না যে এটি টেক্সট ডেটা ধরণের ক্ষেত্রে কীভাবে কাজ করবে। আমি এখন কয়েক বছর ধরে এসকিউএল 2005 এ আছি এবং পাঠের সাথে আর কাজ করার সাথে আর ধর্মান্তরিত নই - তবে আমি মনে করি যে আপনি এটিতে লেফট এবং রাইট ব্যবহার করতে পারবেন?

ফিলিপ


1
দুঃখিত - আমি নিশ্চিত যে আমি 2000 এর সাথে কাজ করার সময় কখনই ফিরে আসিনি, এবং বর্তমানে আমার কোনও এসকিউএল 2000 ইনস্টলসে অ্যাক্সেস নেই।
ফিলিপ কেলি

উজ্জ্বল! এই সমস্যাটিকে আক্রমণ করার জন্য কখনই ভাবেননি!
জেরেদ

4
সুন্দর! আমি আমার নিজের প্রয়োজনের জন্য সংশোধন করেছি: ইমেল.সুবস্ট্রিং (০১, ইমেইল.লাস্ট ইন্ডেক্সঅফ ('@')) == বাম বাছাই করুন (ইমেল, লেন (ইমেল) -চারিডেক্স ('@', উত্তর (ইমেল)))
ফ্রেড্রিক জোহানসন

1
এই মত চালাক স্টাফ কেন প্রোগ্রামিং এত মজাদার!
ক্রিস

অতিরিক্ত উল্টো পরিবর্তে আসল বামের পরিবর্তে ডানদিকে কেন ব্যবহার করবেন না
ফিল

108

সহজ উপায় হ'ল ...

REVERSE(SUBSTRING(REVERSE([field]),0,CHARINDEX('[expr]',REVERSE([field]))))

3
+1 কারন কোনও মিল খুঁজে পাওয়া না গেলে 'অবৈধ দৈর্ঘ্যের প্যারামিটারটি বামে বা সাবস্ট্রাকশন ফাংশনে চলে গেছে' এর মতো অগ্নি ত্রুটি
জিল্মিকি

12
আপনার যদি [expr]1 টির বেশি প্রতীক থাকে তবে আপনার এটিরও বিপরীত হওয়া দরকার!
Andrius Naru Narevičius

60

আপনি যদি স্কেলসারভার 2005 বা তার বেশি ব্যবহার REVERSEকরে থাকেন তবে বহুবার ফাংশন ব্যবহার করা কার্যকারিতার পক্ষে ক্ষতিকারক, নীচের কোডটি আরও কার্যকর।

DECLARE @FilePath VARCHAR(50) = 'My\Super\Long\String\With\Long\Words'
DECLARE @FindChar VARCHAR(1) = '\'

-- Shows text before last slash
SELECT LEFT(@FilePath, LEN(@FilePath) - CHARINDEX(@FindChar,REVERSE(@FilePath))) AS Before
-- Shows text after last slash
SELECT RIGHT(@FilePath, CHARINDEX(@FindChar,REVERSE(@FilePath))-1) AS After
-- Shows the position of the last slash
SELECT LEN(@FilePath) - CHARINDEX(@FindChar,REVERSE(@FilePath)) AS LastOccuredAt

1
এটি অন্ধকারে স্পষ্ট বলে মনে হতে পারে তবে আপনি যদি কোনও একক চরিত্রের পরিবর্তে স্ট্রিং সন্ধান করছেন তবে আপনাকে এটি করতে হবে: লেন (@ ফাইলপ্যাথ) - চরিনডেক্স (রিভার্স (@ ফাইন্ডস্ট্রিং), রিভার্স (@ ফিলিপথ))
pkExec

14
DECLARE @FilePath VARCHAR(50) = 'My\Super\Long\String\With\Long\Words'
DECLARE @FindChar VARCHAR(1) = '\'

SELECT LEN(@FilePath) - CHARINDEX(@FindChar,REVERSE(@FilePath)) AS LastOccuredAt

8

পুরানো তবে এখনও বৈধ প্রশ্ন, তাই এখানে অন্যদের সরবরাহিত তথ্যের ভিত্তিতে আমি কী তৈরি করেছি তা এখানে।

create function fnLastIndexOf(@text varChar(max),@char varchar(1))
returns int
as
begin
return len(@text) - charindex(@char, reverse(@text)) -1
end

7

এটি আমার পক্ষে খুব ভাল কাজ করেছে।

REVERSE(SUBSTRING(REVERSE([field]), CHARINDEX(REVERSE('[expr]'), REVERSE([field])) + DATALENGTH('[expr]'), DATALENGTH([field])))


4

হুম, আমি জানি এটি একটি পুরানো থ্রেড, তবে ট্যালি টেবিলটি এসকিউএল 2000 (বা অন্য কোনও ডাটাবেস) এ এটি করতে পারে:

DECLARE @str CHAR(21),
        @delim CHAR(1)
 SELECT @str = 'Your-delimited-string',
        @delim = '-'

SELECT
    MAX(n) As 'position'
FROM
    dbo._Tally
WHERE
    substring(@str, _Tally.n, 1) = @delim

ট্যালি টেবিল হ'ল ইনক্রিমেন্টিং সংখ্যার একটি টেবিল।

substring(@str, _Tally.n, 1) = @delimপ্রতিটি বিভেদক অবস্থান পায়, তারপর আপনি ঠিক যে সেটে সর্বাধিক অবস্থান পেতে।

ট্যালি টেবিলগুলি দুর্দান্ত। আপনি যদি এগুলি আগে ব্যবহার না করে থাকেন তবে এসকিউএল সার্ভার সেন্ট্রাল (ফ্রি রেগ, বা কেবল বাগ মি নট ( http://www.bugmenot.com/view/sqlservercentral.com )) ব্যবহার করুন article

* সম্পাদনা করুন: সরানো হয়েছে n <= LEN(TEXT_FIELD), কারণ আপনি পাঠ্য প্রকারে LEN () ব্যবহার করতে পারবেন না। যতক্ষণ substring(...) = @delimঅবধি ফলাফল এখনও সঠিক।


খুশী হলাম। আমি মনে করি এটি কার্যকরভাবে একই সমাধান যদিও জিবিএন দ্বারা গৃহীত উত্তর হিসাবে; আপনি কেবলমাত্র 1, 2, 3 ইত্যাদি পূর্ণসংখ্যার সঞ্চয় করতে একটি টেবিল ব্যবহার করছেন যা ডেটালাইএনটিএইচটি থেকে বিয়োগ করা হয় এবং শেষ অক্ষরের পরিবর্তে প্রথম অক্ষর থেকে এগিয়ে নেওয়া হয়।
মাইকেল পেতিটো

2

আপনার স্ট্রিং এবং আপনার স্ট্রস্ট্রিং উভয়ই বিপরীত করুন, তারপরে প্রথম উপস্থিতির সন্ধান করুন।


ভাল যুক্তি. আমার এখন 2000 নেই এবং আমি যখন করতে পারি তখন তা করতে পারতাম কিনা তা মনে করতে পারি না।
একে

2

অন্যান্য উত্তরগুলির মধ্যে কিছু প্রকৃত স্ট্রিং দেয় তবে আমার আসল সূচিপত্রের আরও জানার প্রয়োজন ছিল। এবং যে উত্তরগুলি এমন জিনিসগুলিকে অতিরিক্ত জটিল করে তোলে। অন্যান্য উত্তরগুলির কিছু অনুপ্রেরণা হিসাবে ব্যবহার করে, আমি নিম্নলিখিতগুলি করেছি ...

প্রথমত, আমি একটি ফাংশন তৈরি করেছি:

CREATE FUNCTION [dbo].[LastIndexOf] (@stringToFind varchar(max), @stringToSearch varchar(max))
RETURNS INT
AS
BEGIN
    RETURN (LEN(@stringToSearch) - CHARINDEX(@stringToFind,REVERSE(@stringToSearch))) + 1
END
GO

তারপরে, আপনার ক্যোয়ারিতে আপনি কেবল এটি করতে পারেন:

declare @stringToSearch varchar(max) = 'SomeText: SomeMoreText: SomeLastText'

select dbo.LastIndexOf(':', @stringToSearch)

উপরেরটি 23 টিতে ফিরে আসবে (':' এর শেষ সূচক)

আশা করি কারও পক্ষে এটি কিছুটা সহজ হয়ে গেছে!


2

আমি বুঝতে পারি এটি কয়েক বছরের পুরানো প্রশ্ন, কিন্তু ...

চালু Access 2010, আপনি এটি করতে ব্যবহার করতে পারেন InStrRev()। আশাকরি এটা সাহায্য করবে.


2

এই উত্তরটি এমএস এসকিউএল সার্ভার ২০০৮ ব্যবহার করে (আমার কাছে এমএস এসকিউএল সার্ভার 2000 এ অ্যাক্সেস নেই) তবে ওপি অনুযায়ী যেভাবে দেখছি তা বিবেচনার জন্য 3 পরিস্থিতি। আমি এখানে কোন উত্তর দেওয়ার চেষ্টা করেছি সেগুলি থেকে সেগুলির 3 টিকেই কভার করা হয়েছে:

  1. প্রদত্ত স্ট্রিংয়ে অনুসন্ধানের অক্ষরের সর্বশেষ সূচি ফেরান।
  2. প্রদত্ত স্ট্রিংয়ে অনুসন্ধানের সাব-স্ট্রিংয়ের (কেবলমাত্র একটি একক অক্ষরের চেয়েও বেশি) শেষ সূচিটি ফিরে আসুন।
  3. যদি অনুসন্ধানের অক্ষর বা উপ-স্ট্রিং প্রদত্ত স্ট্রিংয়ের রিটার্নে না থাকে 0

আমি যে ফাংশনটি নিয়ে এসেছি তাতে 2 টি পরামিতি লাগে:

@String NVARCHAR(MAX) : অনুসন্ধান করা স্ট্রিং

@FindString NVARCHAR(MAX) : হয় শেষের সূচকটি পেতে একটি একক অক্ষর বা উপ-স্ট্রিং @String

এটি এমনটি প্রদান করে INTযা হয় হয় এর ইতিবাচক সূচক @FindStringহয় @Stringবা 0যার অর্থ @FindStringহয় না@String

এখানে ফাংশনটি কী করে তার একটি ব্যাখ্যা:

  1. সূচনা @ReturnValকরার 0যে ইঙ্গিত @FindStringনেই@String
  2. ব্যবহার করে @FindStringইন- এর সূচি পরীক্ষা @StringকরেCHARINDEX()
  3. সূচী তাহলে @FindStringমধ্যে @Stringহয় 0, @ReturnValযেমন ছেড়ে দেওয়া হয়0
  4. সূচী তাহলে @FindStringমধ্যে @Stringহয় > 0, @FindStringহয় @String, তাই এটি শেষ সূচক গণনা @FindStringমধ্যে @Stringব্যবহার করেREVERSE()
  5. রিটার্নস @ReturnValযেগুলি হয় একটি ধনাত্মক সংখ্যা শেষ সূচি যে @FindStringমধ্যে @Stringবা 0যে ইঙ্গিত @FindStringনেই@String

এখানে তৈরি ফাংশন স্ক্রিপ্ট (কপি এবং পেস্ট প্রস্তুত):

CREATE FUNCTION [dbo].[fn_LastIndexOf] 
(@String NVARCHAR(MAX)
, @FindString NVARCHAR(MAX))
RETURNS INT
AS 
BEGIN
    DECLARE @ReturnVal INT = 0
    IF CHARINDEX(@FindString,@String) > 0
        SET @ReturnVal = (SELECT LEN(@String) - 
        (CHARINDEX(REVERSE(@FindString),REVERSE(@String)) + 
        LEN(@FindString)) + 2)  
    RETURN @ReturnVal
END

এখানে অল্প কিছু যা সুবিধাজনকভাবে ফাংশনটি পরীক্ষা করে:

DECLARE @TestString NVARCHAR(MAX) = 'My_sub2_Super_sub_Long_sub1_String_sub_With_sub_Long_sub_Words_sub2_'
, @TestFindString NVARCHAR(MAX) = 'sub'

SELECT dbo.fn_LastIndexOf(@TestString,@TestFindString)

আমি কেবল এমএস এসকিউএল সার্ভার ২০০৮ এ এটি চালিয়েছি কারণ আমার অন্য কোনও সংস্করণে অ্যাক্সেস নেই তবে যা আমি এতে দেখেছি তা ২০০++ এর জন্য ভাল হওয়া উচিত।

উপভোগ করুন।


1

আমি জানি যে এটি অদক্ষ হয়ে উঠবে তবে আপনি কি textক্ষেত্রটি কাস্টিংয়ের বিষয়টি বিবেচনা করেছেন varcharযাতে আপনি যে ওয়েবসাইটটি পেয়েছেন তার সরবরাহকৃত সমাধানটি ব্যবহার করতে পারেন? আমি জানি যে এই সমাধানটি সমস্যাগুলি তৈরি করবে কারণ আপনি যদি textক্ষেত্রের দৈর্ঘ্যটি আপনার দৈর্ঘ্যের উপর দিয়ে প্রবাহিত হন varchar(তবে এটি খুব পারফরম্যান্ট হবে না বলে উল্লেখ করবেন না) the

যেহেতু আপনার ডেটা কোনও textক্ষেত্রের মধ্যে রয়েছে (এবং আপনি এসকিউএল সার্ভার 2000 ব্যবহার করছেন) আপনার বিকল্পগুলি সীমিত।


হ্যাঁ, "বর্ণে" কাস্টিং কোনও বিকল্প নয় কারণ ডেটা ঘন ঘন প্রক্রিয়া করা হচ্ছে এমন একটি "বার্চারে" রাখা যেতে পারে এমন সীমা ছাড়িয়ে গেছে। যদিও আপনার উত্তরের জন্য ধন্যবাদ!
রাজ

1

আপনি যদি শব্দের একটি স্ট্রিংয়ে শেষ স্পেসের সূচক পেতে চান, তবে আপনি স্ট্রিংয়ে সর্বশেষ শব্দটি ফিরে পেতে এই অভিব্যক্তিটি রাইট (নাম, (CHARINDEX ('', REVERSE (নাম), 0)) ব্যবহার করতে পারেন This আপনি যদি পুরো এবং শেষ নামটি এবং / বা মাঝের নামটির জন্য আদ্যক্ষর অন্তর্ভুক্ত করে এমন একটি পূর্ণ নামের শেষ নামটি বিশ্লেষণ করতে চান তবে তা সহায়ক is


1

@indexOf = <whatever characters you are searching for in your string>

@LastIndexOf = LEN([MyField]) - CHARINDEX(@indexOf, REVERSE([MyField]))

পরীক্ষিত হয়নি, শূন্য সূচকের কারণে এটি একের পর এক বন্ধ হয়ে যেতে পারে তবে অক্ষর থেকে আপনার স্ট্রিংয়ের শেষের SUBSTRINGদিকে কাটা যখন ফাংশনে কাজ করে@indexOf

SUBSTRING([MyField], 0, @LastIndexOf)


1

এই কোডটি এমনকি স্ট্রিংগুলিতে 1 টির বেশি অক্ষর থাকা সত্ত্বেও কাজ করে।

DECLARE @FilePath VARCHAR(100) = 'My_sub_Super_sub_Long_sub_String_sub_With_sub_Long_sub_Words'
DECLARE @FindSubstring VARCHAR(5) = '_sub_'

-- Shows text before last substing
SELECT LEFT(@FilePath, LEN(@FilePath) - CHARINDEX(REVERSE(@FindSubstring), REVERSE(@FilePath)) - LEN(@FindSubstring) + 1) AS Before
-- Shows text after last substing
SELECT RIGHT(@FilePath, CHARINDEX(REVERSE(@FindSubstring), REVERSE(@FilePath)) -1) AS After
-- Shows the position of the last substing
SELECT LEN(@FilePath) - CHARINDEX(REVERSE(@FindSubstring), REVERSE(@FilePath)) AS LastOccuredAt

0

আমার একটি ফোল্ডারের পথে ব্যাকস্ল্যাশের নবম সর্বশেষ অবস্থানটি সন্ধান করা উচিত। এখানে আমার সমাধান।

/*
http://stackoverflow.com/questions/1024978/find-index-of-last-occurrence-of-a-sub-string-using-t-sql/30904809#30904809
DROP FUNCTION dbo.GetLastIndexOf
*/
CREATE FUNCTION dbo.GetLastIndexOf
(
  @expressionToFind         VARCHAR(MAX)
  ,@expressionToSearch      VARCHAR(8000)
  ,@Occurrence              INT =  1        -- Find the nth last 
)
RETURNS INT
AS
BEGIN

    SELECT  @expressionToSearch = REVERSE(@expressionToSearch)

    DECLARE @LastIndexOf        INT = 0
            ,@IndexOfPartial    INT = -1
            ,@OriginalLength    INT = LEN(@expressionToSearch)
            ,@Iteration         INT = 0

    WHILE (1 = 1)   -- Poor man's do-while
    BEGIN
        SELECT @IndexOfPartial  = CHARINDEX(@expressionToFind, @expressionToSearch)

        IF (@IndexOfPartial = 0) 
        BEGIN
            IF (@Iteration = 0) -- Need to compensate for dropping out early
            BEGIN
                SELECT @LastIndexOf = @OriginalLength  + 1
            END
            BREAK;
        END

        IF (@Occurrence > 0)
        BEGIN
            SELECT @expressionToSearch = SUBSTRING(@expressionToSearch, @IndexOfPartial + 1, LEN(@expressionToSearch) - @IndexOfPartial - 1)
        END

        SELECT  @LastIndexOf = @LastIndexOf + @IndexOfPartial
                ,@Occurrence = @Occurrence - 1
                ,@Iteration = @Iteration + 1

        IF (@Occurrence = 0) BREAK;
    END

    SELECT @LastIndexOf = @OriginalLength - @LastIndexOf + 1 -- Invert due to reverse
    RETURN @LastIndexOf 
END
GO

GRANT EXECUTE ON GetLastIndexOf TO public
GO

এখানে আমার পরীক্ষার কেস যা পাস হয়

SELECT dbo.GetLastIndexOf('f','123456789\123456789\', 1) as indexOf -- expect 0 (no instances)
SELECT dbo.GetLastIndexOf('\','123456789\123456789\', 1) as indexOf -- expect 20
SELECT dbo.GetLastIndexOf('\','123456789\123456789\', 2) as indexOf -- expect 10
SELECT dbo.GetLastIndexOf('\','1234\6789\123456789\', 3) as indexOf -- expect 5

0

ডিলিমিটারের শেষ উপস্থিতির আগে অংশটি পেতে (কেবলমাত্র ব্যবহারের NVARCHARকারণে কাজ করে DATALENGTH):

DECLARE @Fullstring NVARCHAR(30) = '12.345.67890.ABC';

DECLARE @Delimiter CHAR(1) = '.';

SELECT SUBSTRING(@Fullstring, 1, DATALENGTH(@Fullstring)/2 - CHARINDEX(@Delimiter, REVERSE(@Fullstring)));

0

এই উত্তরটি ওপির প্রয়োজনীয়তা পূরণ করে। বিশেষত এটি সূচকে একটি একক চরিত্রের চেয়ে বেশি হতে দেয় এবং যখন খড়ের খড়ের মধ্যে সূচি পাওয়া যায় না তখন এটি ত্রুটি তৈরি করে না। আমার কাছে মনে হয়েছিল যে অন্যান্য উত্তরগুলির বেশিরভাগ (সমস্ত?) এই প্রান্তের মামলাগুলি পরিচালনা করে না। এর বাইরে আমি দেশীয় এমএস এসকিউএল সার্ভার চারআইন্ডেক্স ফাংশন সরবরাহ করে "স্টার্টিং পজিশন" যুক্তি যুক্ত করেছি। আমি বাম থেকে ডান পরিবর্তে ডান থেকে বামে প্রক্রিয়াজাতকরণ ব্যতীত চরআইডেক্সের স্পেসিফিকেশনটি ঠিক আয়ন করার চেষ্টা করেছি। উদাহরণস্বরূপ, আমি সুই বা খড়ের টুকরোটি যদি নাল হয় তবে আমি নাল ফিরে আসি এবং খড়ের খড়ের মধ্যে সূচি পাওয়া না গেলে আমি শূন্য ফিরে আসি। একটি জিনিস যা আমি প্রায় পেতে পারি না তা হ'ল বিল্ট ইন ফাংশন সহ তৃতীয় প্যারামিটার alচ্ছিক is এসকিউএল সার্ভার ব্যবহারকারীর সংজ্ঞায়িত ফাংশনগুলির সাথে, সমস্ত পরামিতি কলটিতে সরবরাহ করা আবশ্যক যদি না ফাংশনটি "এক্সইসিইসি" ব্যবহার করে ডাকা হয় । তৃতীয় প্যারামিটারটি অবশ্যই প্যারামিটার তালিকায় অন্তর্ভুক্ত করা উচিত, আপনি এর জন্য একটি স্থানধারক হিসাবে "ডিফল্ট" কীওয়ার্ডটি কোনও মান না দিয়েই সরবরাহ করতে পারেন (নীচের উদাহরণগুলি দেখুন)। যেহেতু এই ফাংশনটি থেকে তৃতীয় প্যারামিটারটি অপসারণ করা সহজ তবে এটি প্রয়োজন না হলে এটি যুক্ত করা প্রয়োজন হলে আমি এটি এখানে একটি প্রাথমিক পয়েন্ট হিসাবে অন্তর্ভুক্ত করেছি।

create function dbo.lastCharIndex(
 @needle as varchar(max),
 @haystack as varchar(max),
 @offset as bigint=1
) returns bigint as begin
 declare @position as bigint
 if @needle is null or @haystack is null return null
 set @position=charindex(reverse(@needle),reverse(@haystack),@offset)
 if @position=0 return 0
 return (len(@haystack)-(@position+len(@needle)-1))+1
end
go

select dbo.lastCharIndex('xyz','SQL SERVER 2000 USES ANSI SQL',default) -- returns 0
select dbo.lastCharIndex('SQL','SQL SERVER 2000 USES ANSI SQL',default) -- returns 27
select dbo.lastCharIndex('SQL','SQL SERVER 2000 USES ANSI SQL',1) -- returns 27
select dbo.lastCharIndex('SQL','SQL SERVER 2000 USES ANSI SQL',11) -- returns 1

0

আমার একই সমস্যাটির সমাধানের সন্ধান করতে গিয়ে আমি এই থ্রেডটি পেরিয়ে এসেছি যার সঠিক একই চাহিদা ছিল তবে ভিন্ন ধরণের ডাটাবেসের জন্যও ছিল যেটিরও অভাব ছিল REVERSE ফাংশনটিও ছিল না।

আমার ক্ষেত্রে এটি একটি ওপেন এজ (প্রগ্রেস) ডাটাবেসের জন্য ছিল, যার সামান্য আলাদা সিনট্যাক্স রয়েছে। এটি বেশিরভাগ ওরাকল টাইপ করা ডেটাবেসগুলিরINSTR জন্য আমার কাছে ফাংশনটি উপলব্ধ করে

সুতরাং আমি নিম্নলিখিত কোডটি নিয়ে এসেছি:

SELECT 
  INSTR(foo.filepath, '/',1, LENGTH(foo.filepath) - LENGTH( REPLACE( foo.filepath, '/',  ''))) AS IndexOfLastSlash 
FROM foo

তবে, আমার নির্দিষ্ট পরিস্থিতির জন্য ( ওপেন এজ (প্রগতি) ডাটাবেস হওয়া) এর ফলে এটি পছন্দসই আচরণে আসেনি কারণ খালি অক্ষরের পরিবর্তে চরিত্রটি প্রতিস্থাপনের মূল স্ট্রিংয়ের সমান দৈর্ঘ্য দেওয়া হয়েছিল। এটি আমার কাছে খুব বেশি অর্থবোধ করে না তবে আমি নীচের কোড দিয়ে সমস্যাটি বাইপাস করতে সক্ষম হয়েছি:

SELECT 
  INSTR(foo.filepath, '/',1, LENGTH( REPLACE( foo.filepath, '/',  'XX')) - LENGTH(foo.filepath))  AS IndexOfLastSlash 
FROM foo

এখন আমি বুঝতে পেরেছি যে এই কোড টি-এসকিউএল এর জন্য সমস্যার সমাধান করবে না কারণ INSTRফাংশনটির কোনও বিকল্প নেই যা প্রস্তাব করেOccurence সম্পত্তি।

কেবল পুঙ্খানুপুঙ্খভাবে বলার জন্য আমি এই স্কেলার ফাংশনটি তৈরি করার জন্য প্রয়োজনীয় কোডটি যুক্ত করব যাতে এটি উপরের উদাহরণগুলির মতো আমি একইভাবে ব্যবহার করতে পারি।

  -- Drop the function if it already exists
  IF OBJECT_ID('INSTR', 'FN') IS NOT NULL
    DROP FUNCTION INSTR
  GO

  -- User-defined function to implement Oracle INSTR in SQL Server
  CREATE FUNCTION INSTR (@str VARCHAR(8000), @substr VARCHAR(255), @start INT, @occurrence INT)
  RETURNS INT
  AS
  BEGIN
    DECLARE @found INT = @occurrence,
            @pos INT = @start;

    WHILE 1=1 
    BEGIN
        -- Find the next occurrence
        SET @pos = CHARINDEX(@substr, @str, @pos);

        -- Nothing found
        IF @pos IS NULL OR @pos = 0
            RETURN @pos;

        -- The required occurrence found
        IF @found = 1
            BREAK;

        -- Prepare to find another one occurrence
        SET @found = @found - 1;
        SET @pos = @pos + 1;
    END

    RETURN @pos;
  END
  GO

স্পষ্টত এড়াতে, REVERSEফাংশনটি উপলভ্য হলে আপনার এই স্কেলার ফাংশনটি তৈরি করার দরকার নেই এবং আপনি ঠিক এর মতো প্রয়োজনীয় ফলাফল পেতে পারেন:

SELECT
  LEN(foo.filepath) - CHARINDEX('/', REVERSE(foo.filepath))+1 AS LastIndexOfSlash 
FROM foo
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.