Get value from string in specific place - tsql

I'm using T-SQL language and I'm wondering the best way to get specific information from a string.
Example of string :
Category : azd Nom du fichier : 684157 Type de doc : info Id : 21542
The idea is to get the value "684157", which will be always between "fichier :" and "Type".
I have tried with substring and charindex but I miss something.
Here is my code
select substring(com, charindex('fichier : ', com)+len('fichier : '), charindex('Type', com)-charindex('fichier : ', com) + len('Type'))
from myTable

There might be a neater way of doing this but here's a method using CHARINDEX and SUBSTRING.
SELECT SUBSTRING(com,
CHARINDEX('fichier :', com) + LEN('fichier :'), -- start index
CHARINDEX('Type :', com) - (CHARINDEX('fichier :', com) + LEN('fichier :'))) -- length
FROM MyTable
The startIndex is the index of fichier : plus the length of fichier :. The end index is the index of Type :. For SUBSTRING we need to use the start index and the length. To calculate the length of the substring we use the index of Type : and subtract what we calculated for startIndex.

This is what I would do:
SELECT LEFT(S.CutString,CHARINDEX(' Type :',S.CutString)) AS FinalString
FROM (VALUES('Category : azd Nom du fichier : 684157 Type : info Id : 21542'))V(String) --Would be your table
CROSS APPLY (VALUES(STUFF(V.String,1,CHARINDEX('fichier : ',V.String) + LEN('fichier : '),'')))S(CutString);

additional variant:
SELECT parsename(replace(replace(com,'fichier : ','.'), 'Type','.'),2)
FROM MyTable
test:

Related

postgresql Convert array type from a non recurcive terme

I am working on a recurcive query and I work on a guid stocked in a varchar(90) column. But I got an cast type exception from pgAdmin when working with Postgres 11.1
I'm stuck and I don't know what could i do to solve this, if any one can help me.
https://docs.postgresql.fr/8.4/queries-with.html
Postgres CTE : type character varying(255)[] in non-recursive term but type character varying[] overall
with recursive sousSujet(typerefin,coderefin,typerefout,coderefout,type,profondeur,chemin, boucle) as (
SELECT p.typerefin, p.coderefin, p.typerefout , p.coderefout , p.type,1, ARRAY[p.coderefout]::varchar(90)[] ,false
FROM relation p
WHERE p.coderefin='2019094070' and p.typerefin='PROJET'
--union all
union
SELECT p.typerefin, p.coderefin, pr.typerefout, pr.coderefout, p.type ,pr.profondeur+1,
--chemin || pr.coderefout,pr.coderefout = ANY(pr.chemin)
chemin::varchar(90)[] || pr.coderefout,pr.coderefout = ANY(pr.chemin::varchar(90)[])
FROM relation p,sousSujet pr
-- WHERE p.coderefin = pr.coderefout
WHERE p.coderefin = pr.coderefout AND NOT pr.boucle and pr.profondeur < 10
)
SELECT typerefin,coderefin,typerefout,coderefout,type,profondeur
FROM sousSujet
order by coderefout limit 20
ERROR: ERREUR: dans la requête récursive « soussujet », la colonne 7 a le type character varying(90)[] dans le terme non
récursif mais le type global character varying[]
LINE 3: ...oderefin, p.typerefout , p.coderefout , p.type,1, ARRAY[p.co...
^
HINT: Convertit la sortie du terme non récursif dans le bon type.
The easiest is to cast everything to text, by using ARRAY[p.coderefout::text] in the anchor query and chemin::text || pr.coderefout in the recursive query. There is no need to cast everything to an array
with recursive sousSujet(typerefin,coderefin,typerefout,coderefout,type,profondeur,chemin, boucle) as (
SELECT p.typerefin, p.coderefin, p.typerefout, p.coderefout, p.type, 1,
ARRAY[p.coderefout::text], false
FROM relation p
WHERE p.coderefin='2019094070' and p.typerefin='PROJET'
union all
SELECT p.typerefin, p.coderefin, pr.typerefout, pr.coderefout, p.type ,pr.profondeur+1,
chemin::text|| pr.coderefout,
pr.coderefout = ANY(pr.chemin)
FROM relation p
join sousSujet pr
on p.coderefin = pr.coderefout
AND NOT pr.boucle
and pr.profondeur < 10
)
SELECT typerefin,coderefin,typerefout,coderefout,type,profondeur
FROM sousSujet
order by coderefout limit 20
The error complains that the term
ARRAY[p.coderefout]::varchar(90)[]
in the non-recursive part has type varchar(90)[], but the corresponding expression
chemin::varchar(90)[] || pr.coderefout
in the recursive part has type varchar[].
This is because the array concatenation operator || removes the type modifier:
SELECT '{a,b,c}'::varchar(90)[] || 'd'::varchar(90) \gdesc
Column | Type
----------+---------------------
?column? | character varying[]
(1 row)
You's have to add an explicit cast to the result of the concatenation:
(chemin || pr.coderefout)::varchar(90)[]
To avoid annoyances like that, don't use type modifiers there. I'd just use varchar or shorter, but synonymous, text. You are not using the column in the final result anyway.

Concat values to string array postgres

I want to reach following structure:
["687ccca","da075bd","4194d"]
and try to achieve it like this:
UPDATE table1
SET "ids"= CONCAT ('[', result, ']')
FROM (SELECT string_agg( id::character varying, ', ')
FROM table2 where "name" like '%W11%'
or "name" like '%12%'
or "name" like '%13%'
or "name" like '%5%'
or "name" like '%W9%'
or "name" like '%74%'
) AS result
WHERE "ids"='all';
however I get this:
[("df6bd58d, 26e094b, 637c1, 4a8cf387ff43c5, 9b0bf9f")]
How do I remove ( and ) and add " after each id?
I believe you want to get an JSON array:
demo:db<>fiddle
SELECT
json_agg(your_texts)
FROM
your_table
If you really want text you can cast this result with ::text into a text afterwards:
json_agg(your_texts)::text

Substring from an escape character onwards

I'm using PostgreSQL and I need to truncate a text string, I need to show from an escape character (:) onwards.
I'm trying something like that:
SELECT SUBSTRING ('CATEGORIA DE TRABAJOS: EJECUTIVO' FROM '%#":#"%' FOR '#');
t=# select split_part('CATEGORIA DE TRABAJOS: EJECUTIVO',':',2);
split_part
------------
EJECUTIVO
(1 row)
just split by first found delimiter?..

How can I query against a concatenated field?

I would like to search for a first name and surname in two sql fields using entity framework. Below is some example code where I am searching for searchString as a concatenation of firstname and lastname database strings.
using(var ent = new testEntities)
{
ent.Contacts.Where(u => (u.firstname + ' ' + u.lastname).contains(searchString))
}
Searching a single field is easy but how could I query for a string which is a concatenation of two database fields.
From the comments: [I get an error] about unable to create a constant value of type char.
The problem with your expression is the way you add a space in between the first and second string. EF knows how to translate string concatenation to SQL, but it does not know how to translate + between a field of string type and space ' ', a constant of type char.
Replacing concatenation expression with u.firstname + " " + u.lastname will fix the problem, because the space " " is now a string literal, not a char constant.
Replace code with below code that will help you i think.
using(var ent = new testEntities)
{
ent.Contacts.Where(u => (u.firstname + " " + u.lastname).contains(searchString))
}

How to represent spaces in Perl's DBI properly

I have a record in an Informix table. The table columns look like this:
acct_no integer,
suffix char(1),
meter_num char(20),
date_read datetime year to second not null ,
counter smallint,
reading integer not null ,
typeofread char(1),
estimated char(1),
time_billed datetime year to second
Using Informix's dbaccess tool:
select *
from ws_mtrread
where acct_no = 113091000
and suffix = " "
order by date_read desc;
this result (newest shown) is returned and works whether or not I use one or two spaces for suffix.
acct_no 113091000
suffix
meter_num 34153205
date_read 2013-09-09 23:31:15
counter 0
reading 1240
typeofread g
estimated
time_billed 2013-10-22 11:48:21
However, this Perl DBI query
my $sql_statement =
"select * ".
"from ws_mtrread ".
"where acct_no = ? ".
"and suffix = ? ".
"order by date_read desc ; ";
does not work. I can fetch the row without specifying $suffix, so I know the row exists.
I believe this is an error on my part in representing the suffix. In this example suffix is equal to a string of two spaces.
How do I represent spaces correctly, so the query works? Here is the rest of the code I used to fetch the row.
my $test_acct_no = 113091000;
my $suffix = " ";
my $pt_sel_hdl = $DBHdl->prepare($sql_statement);
$pt_sel_hdl->execute($test_acct_no, $DBHdl->quote($suffix));
my $ws_mtr_read_rec_ref = $pt_sel_hdl->fetchrow_hashref;
After the call, $ws_mtr_read_rec_ref is undefined.
Don't use DBI's quote method here:
$pt_sel_hdl->execute($test_acct_no, $DBHdl->quote($suffix));
When you use ? placeholders in your SQL, the database driver will correctly parameterize the query arguments that you pass to execute. You are probably creating a query that is searching for the literal string " " (including the quotes) when you want to search for (just two spaces.)
So this should be all you need:
$pt_sel_hdl->execute($test_acct_no, $suffix);