January 20, 2020 at 6:46 pm
Good morning all
i need your expertise to help me on a code
the goal is to extract part of a chain
create table DATACONTENT
(
line varchar(max)
)
insert into DATACONTENT values ('\\A1-SRV-05\REPRISE-sollyaza\Allian_ged\NOVAXEL\ALLIAN_1\C842183\CARREFOUR SANTE REPRISE\160010210006\documents entrants\Courriers divers_12470290.pdf')
insert into DATACONTENT values (
'\\A1-SRV-05\REPRISE-sollyaza\Allian_ged\NOVAXEL\ALLIANZ_1\CAL000010\Volvo Allianz\VAZP100027\documents entrants\001-Doc 02 mars 2018 à 1640_22459358.pdf')
insert into DATACONTENT values (
'\\A1-SRV-05\REPRISE-sollyaza\Allian_ged\NOVAXEL\ALLIANZ_1\CAL000027\Volvo Allianz\VAZP100002\documents entrants\Gestion Contrat Volvo - Votre Contrat VAZP100002_16821788.MSG')
insert into DATACONTENT values (
'\\A1-SRV-05\REPRISE-sollyaza\Allian_ged\NOVAXEL\ALLIANZ_1\CAL023013\Ford Assurance Automobile\FORP05090\documents entrants\Retour AR_19178619.pdf')
I must recover for each insertion the value of the ref_contrat which corresponds to
160010210006
VAZP100027
VAZP100002
FORP05090
thanks for your help
January 20, 2020 at 7:02 pm
You need to split your string on the backslash and choose the 10th item. Here's an example using the infamous DelimitedSplit8k (notice how I changed your tabledef to VARCHAR(8000) to make best use of it).
DROP TABLE IF EXISTS #DataContent;
CREATE TABLE #DATACONTENT
(
line VARCHAR(8000) NOT NULL
);
INSERT INTO #DATACONTENT
(
line
)
VALUES
('\\A1-SRV-05\REPRISE-sollyaza\Allian_ged\NOVAXEL\ALLIAN_1\C842183\CARREFOUR SANTE REPRISE\160010210006\documents entrants\Courriers divers_12470290.pdf')
,('\\A1-SRV-05\REPRISE-sollyaza\Allian_ged\NOVAXEL\ALLIANZ_1\CAL000010\Volvo Allianz\VAZP100027\documents entrants\001-Doc 02 mars 2018 à 1640_22459358.pdf')
,('\\A1-SRV-05\REPRISE-sollyaza\Allian_ged\NOVAXEL\ALLIANZ_1\CAL000027\Volvo Allianz\VAZP100002\documents entrants\Gestion Contrat Volvo - Votre Contrat VAZP100002_16821788.MSG')
,('\\A1-SRV-05\REPRISE-sollyaza\Allian_ged\NOVAXEL\ALLIANZ_1\CAL023013\Ford Assurance Automobile\FORP05090\documents entrants\Retour AR_19178619.pdf');
SELECT d.line
,s1.Item
FROM #DATACONTENT d
CROSS APPLY
(SELECT * FROM dbo.DelimitedSplit8K(d.line, '\') dsk ) s1
WHERE s1.ItemNumber = 10;
The absence of evidence is not evidence of absence.
Martin Rees
You can lead a horse to water, but a pencil must be lead.
Stan Laurel
January 20, 2020 at 7:28 pm
A different approach would be to tackle this at the application level. The application will grab the entire string from the database and split it in C# (or whichever language you prefer).
If this NEEDS to be done on the SQL Server side, Phil's solution is likely going to be the best bet. Or if you upgrade to SQL 2016, there is a built-in string splitting function that could handle it without needing to create the DelimitedSplit8k function.
Every case that I have had where I need to work with string splitting, splitting and managing it on the application layer has had better performance.
The above is all just my opinion on what you should do.
As with all advice you find on a random internet forum - you shouldn't blindly follow it. Always test on a test server to see if there is negative side effects before making changes to live!
I recommend you NEVER run "random code" you found online on any system you care about UNLESS you understand and can verify the code OR you don't care if the code trashes your system.
January 20, 2020 at 8:25 pm
Or if you upgrade to SQL 2016, there is a built-in string splitting function that could handle it without needing to create the DelimitedSplit8k function.
You're referring to STRING_SPLIT(), I presume.
What this function does not do is provide the ordinal position of the split strings.
I just tried this unstable-looking idea
WITH ordered AS (
SELECT *, ro = ROW_NUMBER() OVER (PARTITION BY d.line ORDER BY (SELECT NULL))
FROM #DATACONTENT d
CROSS APPLY
STRING_SPLIT(d.line,'\') ss)
SELECT * FROM ordered WHERE ro = 10
It seems to work in this case, but I wouldn't trust it in a production scenario.
The absence of evidence is not evidence of absence.
Martin Rees
You can lead a horse to water, but a pencil must be lead.
Stan Laurel
January 20, 2020 at 10:21 pm
STRING_SPLIT also does not guarantee the order of the strings returned (in keeping with relational theory). That is, you can't be sure that the 10th value that comes out will be the 10th value that was in the string. It might be, but then again, it might not.
SQL DBA,SQL Server MVP(07, 08, 09) "It's a dog-eat-dog world, and I'm wearing Milk-Bone underwear." "Norm", on "Cheers". Also from "Cheers", from "Carla": "You need to know 3 things about Tortelli men: Tortelli men draw women like flies; Tortelli men treat women like flies; Tortelli men's brains are in their flies".
January 20, 2020 at 11:04 pm
Remarks
STRING_SPLIT inputs a string that has delimited substrings, and inputs one character to use as the delimiter or separator. STRING_SPLIT outputs a single-column table whose rows contain the substrings. The name of the output column is value.
The output rows might be in any order. The order is not guaranteed to match the order of the substrings in the input string. You can override the final sort order by using an ORDER BY clause on the SELECT statement (ORDER BY value
).
https://docs.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql?view=sql-server-ver15
January 21, 2020 at 2:10 am
I was reading that document from microsoft too and I think I interpreted it differently (and incorrectly) than everyone else. I read it as the order is not guaranteed as you can put in an ORDER BY. Which I didn't really understand why they bothered to state that. But then re-read it and it starts with "the output rows might be in any order". So yeah, string_split in this case is not a valid option.
In all of the examples I have seen and tested on my system (which is not an exhaustive list), it seems like the order for the output is always the same as the input UNLESS you specify to order it differently. That being said, it could be the examples I tried were not good ones that cause the row order to come out differently or maybe you need a larger data set for the order to go crazy. But since the results could come out in any order, I agree that this is likely not a good route.
My personal preference for string splitting is still in the application layer though...
The above is all just my opinion on what you should do.
As with all advice you find on a random internet forum - you shouldn't blindly follow it. Always test on a test server to see if there is negative side effects before making changes to live!
I recommend you NEVER run "random code" you found online on any system you care about UNLESS you understand and can verify the code OR you don't care if the code trashes your system.
January 22, 2020 at 5:09 pm
You could try something like this to make it work.
CREATE TABLE #DATACONTENT(line VARCHAR(MAX))
INSERT INTO #DATACONTENT VALUES ('\\A1-SRV-05\REPRISE-sollyaza\Allian_ged\NOVAXEL\ALLIAN_1\C842183\CARREFOUR SANTE REPRISE\160010210006\documents entrants\Courriers divers_12470290.pdf')
INSERT INTO #DATACONTENT VALUES ('\\A1-SRV-05\REPRISE-sollyaza\Allian_ged\NOVAXEL\ALLIANZ_1\CAL000010\Volvo Allianz\VAZP100027\documents entrants\001-Doc 02 mars 2018 à 1640_22459358.pdf')
INSERT INTO #DATACONTENT VALUES ('\\A1-SRV-05\REPRISE-sollyaza\Allian_ged\NOVAXEL\ALLIANZ_1\CAL000027\Volvo Allianz\VAZP100002\documents entrants\Gestion Contrat Volvo - Votre Contrat VAZP100002_16821788.MSG')
INSERT INTO #DATACONTENT VALUES ('\\A1-SRV-05\REPRISE-sollyaza\Allian_ged\NOVAXEL\ALLIANZ_1\CAL023013\Ford Assurance Automobile\FORP05090\documents entrants\Retour AR_19178619.pdf')
SELECT REVERSE(SUBSTRING(REVERSE(line),1,CHARINDEX('\',REVERSE(line),0)-1)), * FROM #DATACONTENTWHERE AS line LIKE '%\160010210006\%'
DROP TABLE #DATACONTENT
January 30, 2020 at 1:41 pm
Here's another way of doing it using cross applys to work through the backslashes:
SELECT i.Result, a.line
FROM DATACONTENT a
CROSS APPLY(VALUES (SUBSTRING(a.line,CHARINDEX('\',a.line,3)+1,8000))) b(line)
CROSS APPLY(VALUES (SUBSTRING(b.line,CHARINDEX('\',b.line)+1,8000))) c(line)
CROSS APPLY(VALUES (SUBSTRING(c.line,CHARINDEX('\',c.line)+1,8000))) d(line)
CROSS APPLY(VALUES (SUBSTRING(d.line,CHARINDEX('\',d.line)+1,8000))) e(line)
CROSS APPLY(VALUES (SUBSTRING(e.line,CHARINDEX('\',e.line)+1,8000))) f(line)
CROSS APPLY(VALUES (SUBSTRING(f.line,CHARINDEX('\',f.line)+1,8000))) g(line)
CROSS APPLY(VALUES (SUBSTRING(g.line,CHARINDEX('\',g.line)+1,8000))) h(line)
CROSS APPLY(VALUES (LEFT(h.line,CHARINDEX('\',h.line)-1))) i(Result)
Viewing 9 posts - 1 through 8 (of 8 total)
You must be logged in to reply to this topic. Login to reply