SAP HANA GUID conversion - guid

in SAP HANA
How can I convert from GUID_C22 data type (16 byte UUID 22) to GUID_X16 (UUID 16 raw).
I'm expeting something like:
UUID22: 051Mf5p07jQZifdyH4x5}0 -> UUID16: 0050563C56401D36A348F362444845FC
I tried with:
hextoraw(UUID22)
but is not working.

UUID22 and UUID16 are ABAP data types that don't exist on SAP HANA. Therefore there is no built-in conversion function available.
However, you might want to check SCN on this one, as this topic had been discussed there before a couple of times. E.g. SCN
Convert GUID_X16 to GUID_C22

You must cut in pieces of length 3 the HEX representation of the created UUID and convert each of them into a two character piece of only the digits, the lowercase and uppercase latin letters and the opening and closing curly brace. I created a conversion table uuid_conv with two columns, hex:CHAR(3) and c22:CHAR(2) for this purpose with content:
hex c22
--- ---
000 00
001 01
...
03C 0y
03D 0z
03E 0{
03F 0}
...
FFB }x
FFC }y
FFD }z
FFE }{
FFF }}
Use your favourite spreadsheet to generate the necessary content.
Afterwards I joined it something like the following:
with uuid as (
select to_varchar(sysuuid) uuid from dummy
),
y as (
select uuid, substring(uuid, 1, 3) as ta,
substring(uuid, 4, 3) as tb,
substring(uuid, 7, 3) as tc,
substring(uuid, 10, 3) as td,
substring(uuid, 13, 3) as te,
substring(uuid, 16, 3) as tf,
substring(uuid, 19, 3) as tg,
substring(uuid, 22, 3) as th,
substring(uuid, 25, 3) as ti,
substring(uuid, 28, 3) as tj,
'0'||substring(uuid, 31, 2) as tk
from uuid )
select uuid, ck.c22 || cj.c22 || ci.c22 || ch.c22 || cg.c22
|| cf.c22 || ce.c22 || cd.c22 || cc.c22 || cb.c22 || ca.c22
from y
inner join uuid_conv ca on (ca.hex = ta)
inner join uuid_conv cb on (cb.hex = tb)
inner join uuid_conv cc on (cc.hex = tc)
inner join uuid_conv cd on (cd.hex = td)
inner join uuid_conv ce on (ce.hex = te)
inner join uuid_conv cf on (cf.hex = tf)
inner join uuid_conv cg on (cg.hex = tg)
inner join uuid_conv ch on (ch.hex = th)
inner join uuid_conv ci on (ci.hex = ti)
inner join uuid_conv cj on (cj.hex = tj)
inner join uuid_conv ck on (ck.hex = tk)
A similar construction with SQLSCRIPT functions can be thought of and would be superior.

Related

How to return all rows in a column when using cross apply and DelimitedSplit8K_LEAD together in SQL Server?

This code works to return the info that I need from the column but IT IS ONLY RETURNING ONE ROW and I need it to return them all.
You can leverage the DelimitedSplit8K_LEAD function which you can read more about here. https://www.sqlservercentral.com/articles/reaping-the-benefits-of-the-window-functions-in-t-sql-2 You will also find the code for the function there.
select FirstValue = max(case when s.ItemNumber = 12 then s.Item end)
, SecondValue = max(case when s.ItemNumber = 45 then try_convert(datetime, stuff(stuff(stuff(s.Item, 9, 0, ' '), 12, 0, ':'), 15, 0, '.')) end)
from myDatabase x
cross apply DelimitedSplit8K_LEAD(x.myColumn, ',') s
where s.ItemNumber = 12
or s.ItemNumber = 45
Here is an example of the data in the column that I'm trying to return.
,505611,XXXXXXX,,,,,,,,,13M2,,,,,,,,,,,03294961,,,,,,,,,,,,,,,,,,,,,XXXXX,20220216183348,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,US,,,0000,,,,,,,,,,,,,,,,,,,,
Here is an example of it working, just not with using it on the table column https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=ca74e807853eb1dea445a8ffb7209b70
Okay so here is an example. Create a table in sql server database...
CREATE TABLE honda
(
user1 nvarchar(max)
);
INSERT INTO honda
(user1)
VALUES
(',523869,HXMFG-01,,,,,,,,,11M2,,,,,,,,,,,03311141,,,,,,,,,,,,,,,,,,,,,EAGLE,20220323082041,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,US,,,0000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'),
(',523869,HXMFG-01,,,,,,,,,12M2,,,,,,,,,,,03311148,,,,,,,,,,,,,,,,,,,,,EAGLE,20220323093049,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,US,,,0000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'),
(',523869,HXMFG-01,,,,,,,,,13M2,,,,,,,,,,,03311216,,,,,,,,,,,,,,,,,,,,,EAGLE,20220323100350,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,US,,,0000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'),
(',523869,HXMFG-01,,,,,,,,,14M2,,,,,,,,,,,03311242,,,,,,,,,,,,,,,,,,,,,EAGLE,20220323103854,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,US,,,0000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'),
(',523869,HXMFG-01,,,,,,,,,15M2,,,,,,,,,,,03311267,,,,,,,,,,,,,,,,,,,,,EAGLE,20220323112420,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,US,,,0000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'),
(',527040,HXMFG-01,,,,,,,,,16M2,,,,,,,,,,,03311352,,,,,,,,,,,,,,,,,,,,,EAGLE,20220323122930,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,US,,,0000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'),
(',527040,HXMFG-01,,,,,,,,,17M2,,,,,,,,,,,03311395,,,,,,,,,,,,,,,,,,,,,EAGLE,20220323130347,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,US,,,0000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,');
If using sql server should only have to run this middle block of code once.
CREATE FUNCTION [dbo].[DelimitedSplit8K_LEAD]
--===== Define I/O parameters
(#pString VARCHAR(8000), #pDelimiter CHAR(1))
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
--===== "Inline" CTE Driven "Tally Table” produces values from 0 up to 10,000...
-- enough to cover VARCHAR(8000)
WITH E1(N) AS (
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
), --10E+1 or 10 rows
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS (--==== This provides the "zero base" and limits the number of rows right up front
-- for both a performance gain and prevention of accidental "overruns"
SELECT 0 UNION ALL
SELECT TOP (DATALENGTH(ISNULL(#pString,1))) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
),
cteStart(N1) AS (--==== This returns N+1 (starting position of each "element" just once for each delimiter)
SELECT t.N+1
FROM cteTally t
WHERE (SUBSTRING(#pString,t.N,1) = #pDelimiter OR t.N = 0)
)
--===== Do the actual split. The ISNULL/NULLIF combo handles the length for the final element when no delimiter is found.
SELECT ItemNumber = ROW_NUMBER() OVER(ORDER BY s.N1),
Item = SUBSTRING(#pString,s.N1,ISNULL(NULLIF((LEAD(s.N1,1,1) OVER (ORDER BY s.N1) - 1),0)-s.N1,8000))
FROM cteStart s
;
GO
If using dbfiddle take the GO off of the end in the above block.
select ECI_Level = max(case when s.ItemNumber = 12 then s.Item end)
, 'DateTime' = max(case when s.ItemNumber = 45 then try_convert(datetime, stuff(stuff(stuff(s.Item, 9, 0, ' '), 12, 0, ':'), 15, 0, '.')) end)
from honda x
cross apply DelimitedSplit8K_LEAD(x.user1, ',') s
where s.ItemNumber = 12
or s.ItemNumber = 45
I was able to get it to work by adding GROUP BY like this...
select ECI_Level = max(case when s.ItemNumber = 12 then s.Item end)
, 'DateTime' = max(case when s.ItemNumber = 45 then try_convert(datetime, stuff(stuff(stuff(s.Item, 9, 0, ' '), 12, 0, ':'), 15, 0, '.')) end)
from honda x
cross apply DelimitedSplit8K_LEAD(x.user1, ',') s
where s.ItemNumber = 12
or s.ItemNumber = 45
GROUP BY user1;
The problem is that you are aggregating over the whole honda table, rather than just over the split data.
You need to place the aggregation into an APPLY
select s.*
from honda x
CROSS apply (
SELECT ECI_Level = max(case when s.ItemNumber = 12 then s.Item end)
, DateTime = max(case when s.ItemNumber = 45 then try_convert(datetime, stuff(stuff(stuff(s.Item, 9, 0, ' '), 12, 0, ':'), 15, 0, '.')) end)
FROM DelimitedSplit8K_LEAD(x.user1, ',') s
where s.ItemNumber = 12
or s.ItemNumber = 45
) s;
db<>fiddle
Personally, for just two values I wouldn't bother with a split function. Instead you can use CHARINDEX, feeding each one into the next to get the next , location.
And I guess this just shows why you shouldn't store data in a database like this in the first place.

Why does this CosmosDB SubQuery fail?

I am trying to use a simple subquery to get a value but I get an error about cardinality
Query as follows:
SELECT va.variantId AS ItemNo,
c.Season,
SUBSTRING(va.variantId, 0, 7) AS ProductNo,
SUBSTRING(va.variantId, 0, 10) AS ArticleNo,
SUBSTRING(va.variantId, 0, 13) AS VariantNo,
(
SELECT VALUE p["value"]
FROM c
JOIN p IN c.OriginalData.presentation.productNameLong
WHERE c.ItemNo = '123456'
AND p.locale = 'en-GB'
AND c.Season = '201808'
AND c.brand = 'xxx'
) AS Title
FROM c
JOIN sm IN c.OriginalData.base.sales.summary.salesMarkets
JOIN ar IN sm.articles
JOIN va IN ar.variants
JOIN ch IN va.channels
WHERE c.ItemNo = '123456'
AND sm.salesMarket = 'SE'
AND ch.channelName = 'xxx'
The error is as follows:
Failed to query item for container rawdata:
Gateway Failed to Retrieve Query Plan: Message: {"errors":[{"severity":"Error","location":{"start":227,"end":498},"code":"SC2201","message":"The cardinality of a scalar subquery result set cannot be greater than one."}]}
ActivityId: 11ff3b08-d8a7-4737-9111-81f319cf1dc5, Microsoft.Azure.Documents.Common/2.11.0, Microsoft.Azure.Documents.Common/2.11.0
The result of that subquery can only ever be 1 single result so I am not sure what it is complaining about
You need to use ARRAY expression to construct an array from subquery's results.
Please try this SQL:
SELECT va.variantId AS ItemNo,
c.Season,
SUBSTRING(va.variantId, 0, 7) AS ProductNo,
SUBSTRING(va.variantId, 0, 10) AS ArticleNo,
SUBSTRING(va.variantId, 0, 13) AS VariantNo,
ARRAY(
SELECT VALUE p["value"]
FROM c
JOIN p IN c.OriginalData.presentation.productNameLong
WHERE c.ItemNo = '123456'
AND p.locale = 'en-GB'
AND c.Season = '201808'
AND c.brand = 'xxx'
) AS Title
FROM c
JOIN sm IN c.OriginalData.base.sales.summary.salesMarkets
JOIN ar IN sm.articles
JOIN va IN ar.variants
JOIN ch IN va.channels
WHERE c.ItemNo = '123456'
AND sm.salesMarket = 'SE'
AND ch.channelName = 'xxx'

SQLITE query GROUP BY with SUM Using Delphi and Zeos

I have an app created using Delphi XE3 accessing the SQLite database with Zeos Component.
A select command in SQLite that return 3 rows:
select p.descricao, pg.valor
from pagamento pg
inner join venda v on pg.origem = 'venda' and v.id_venda = pg.id_origem
left join pagamento_tipo p on pg.id_pagamento_tipo = p.id_pagamento_tipo
where v.data >= '2021-01-19' and v.data <= '2021-01-19'
and v.ra_status_venda in ( 'Finalizado', 'Pedido')
but when I put the group command the information result is wrong.
select p.descricao, sum(pg.valor) as valor
from pagamento pg
inner join venda v on pg.origem = 'venda' and v.id_venda = pg.id_origem
left join pagamento_tipo p on pg.id_pagamento_tipo = p.id_pagamento_tipo
where v.data >= '2021-01-19' and v.data <= '2021-01-19'
and v.ra_status_venda in ( 'Finalizado', 'Pedido')
group by descricao
the P02 not sum.
and, if I sum all row, without group by, the value was correct too.
select sum(pg.valor) as valor
from pagamento pg
inner join venda v on pg.origem = 'venda' and v.id_venda = pg.id_origem
left join pagamento_tipo p on pg.id_pagamento_tipo = p.id_pagamento_tipo
where v.data >= '2021-01-19' and v.data <= '2021-01-19'
and v.ra_status_venda in ( 'Finalizado', 'Pedido')
PS: in another period this commands sum correctly.
PS2 I'm using dll 32bits for windows.
With tips #Shawn and #forpas I solve this problem, the SQLite type of field NUMERIC converts the numbers to other types in the RUNTIME select command, how the two first values were INTEGER and the last value were Real, apparently my program not recognize two different types in the same column.
To solve I change the type of field in the database from NUMERIC to REAL.

How to fix ‘SQL stored procedure’ error in ASP.Net to show two Select result in Chart column

I want to link stored procedure to ASP.net Chart with two select query to show result in many series. This for my web application, running against SQL Server 2008 and Visual Studio 2015.
I've tried to link chart series to stored procedure but I can't show this two results on the ASP chart datasource. The results contain first select statement only.
SELECT
User_.[User_name],
CONVERT(INT, ROUND(SUM((Result.Evaluation_data) * 100) / (10 * (COUNT(Result.Evaluation_id))), 0)) AS InTeam
FROM
Result
INNER JOIN
User_ ON Result.Evaluated_user_id = User_.[User_id]
WHERE
(Result.Evaluation_id = 1 OR Result.Evaluation_id = 2)
AND result.Evaluation_did_user != Result.Evaluated_user_id
AND Result.Evaluated_user_id IN (SELECT [user_id] FROM user_
WHERE user_.team_code = 1)
AND Result.Evaluation_did_user IN (SELECT [user_id] FROM user_
WHERE user_.team_code = 1)
GROUP BY
User_.[User_name]
ORDER BY
User_.[User_name]
SELECT
User_.[User_name],
CONVERT(INT, ROUND(SUM((Result.Evaluation_data) * 100) / (10 * (COUNT(Result.Evaluation_id))), 0)) AS OutOFTeam
FROM
Result
INNER JOIN
User_ ON Result.Evaluated_user_id = User_.[User_id]
WHERE
(Result.Evaluation_id = 1 OR Result.Evaluation_id = 2)
AND result.Evaluation_did_user != Result.Evaluated_user_id
AND Result.Evaluated_user_id IN (SELECT [user_id] FROM user_
WHERE user_.team_code = 1)
AND Result.Evaluation_did_user IN (SELECT [user_id] FROM user_
WHERE user_.team_code != 1)
GROUP BY
User_.[User_name]
ORDER BY
User_.[User_name]

Use check box selected elements to filter report

I have an issue with making a correct report for my application. The report is supposed to return free rooms for a set of parameters (including a list of equipements). However, I cannot include the equipements search in my interractive report.
Here is the SQL request I've got:
SELECT s.code || ' ' || s.nom as Salle, s.capacite, LISTAGG(eq.libelle, ', ') WITHIN GROUP (ORDER BY eq.code) as Equipements, b.libelle as Batiment, s.numero
FROM SALLES s
INNER JOIN batiments b ON
b.numero = s.bat_numero
INNER JOIN sal_gpe sg ON
s.numero = sg.sal_numero
INNER JOIN groupespersonnes gp ON
gp.numero = sg.gpe_numero
LEFT JOIN equ_sal e ON
e.sal_numero = s.numero
LEFT JOIN equipements eq ON
eq.numero = e.equ_numero
-- On vérifie les salles visibles pour le groupe de personne affecté à l'utilisateur connecté.
WHERE gp.code = (SELECT code FROM groupespersonnes INNER JOIN personnes p ON p.gpe_numero = groupespersonnes.numero WHERE UPPER(:APP_USER) = UPPER(p.username))
AND :P30_PERIODE_DEBUT NOT IN (SELECT per_numero FROM enregistrements WHERE sal_numero = s.numero AND TO_CHAR(jour, 'DD.MM.RR') = :P30_DATE)
AND :P30_PERIODE_FIN NOT IN (SELECT per_numero FROM enregistrements WHERE sal_numero = s.numero AND TO_CHAR(jour, 'DD.MM.RR') = :P30_DATE)
AND e.equ_numero = regexp_substr(:P30_EQUIPEMENTS,'[^:]+')
GROUP BY s.capacite, s.nom, b.libelle, s.numero, s.code
I'm doing a LISTAGG on the equipements, so that I can show all the equipements for one room fit in one cell. Now :P30_EQUIPEMENT is actually a STRING. It takes the number of the equipements selected from the checkbox list (Dynamic LOV), and separates them with a ":". I've been trying many solutions but nothing worked. I'm now diving in the PL/SQL option.
If you have a idea of an easier way, I'd gladly take it.
If this is what :P30_EQUIPMENTS contains, then you should:
SQL> with test (p30_equipments) as
2 (select 'tv:balcony:shower' from dual)
3 select regexp_substr(p30_equipments, '[^:]+', 1, level) equipment
4 from test
5 connect by level <= regexp_count(p30_equipments, ':') + 1;
EQUIPMENT
-----------------
tv
balcony
shower
SQL>
i.e. applied to your code:
and e.equ_numero in (select regexp_substr(:p30_equipments, '[^:]+', 1, level)
from dual
connect by level <= regexp_count(:p30_equipments, ':') + 1
)

Resources