Hashbytes MD5 syntax - hash

Why do the hashed results below differ? Shouldn't they be the same?
SELECT [teststring]
, SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('MD5', [teststring])), 3, 32)
, SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('MD5', 'HelloWorld')), 3, 32)
FROM [test]
WHERE [teststring]='HelloWorld'
HelloWorld 87434a4b7918d288dc1c1e0ca7544e77 68e109f0f40ca72a15e05cc22786f8e6

I can reproduce this, it would appear that your column is storing an NVARCHAR rather than a VARCHAR (which is what you have specified your string as in your query), these are stored differently and will therefore give different results.
If you run the following query you should see that they are the same when using the same datatype (NVARCHAR):
SELECT [teststring]
, SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('MD5', [teststring])), 3, 32)
, SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('MD5', N'HelloWorld')), 3, 32)
FROM [test]
WHERE [teststring]='HelloWorld'

Related

Syntax to manually insert a UUID value in Postgres

I have a table that was created as such:
CREATE TABLE IF NOT EXISTS DIM_Jour (
jour_id uuid NOT NULL,
AAAA int,
MM int,
JJ int,
Jour_Semaine int,
Num_Semaine int,
PRIMARY KEY (jour_id)
);
I'm trying to manually insert some value for testing purposes. I know that eventually I would need to use a UUID generator.
INSERT INTO DIM_Jour (jour_id, AAAA, MM, JJ, Jour_Semaine, Num_Semaine) VALUES (
292a485f-a56a-4938-8f1a-bbbbbbbbbbb1,
2020,
11,
19,
4,
47
);
I get this error (or similar)
ERROR: syntax error at or near "a485f"
LINE 3: 292a485f-a56a-4938-8f1a-bbbbbbbbbbb1,
^
I've tried the different formats mentioned in the Postgres documentation, but it seems like it doesn't except any format. Is it a stupid syntax issue or am I missing something here? What is the correct syntax?
You could pass it as a string literal and have the database implicitly convert it to a UUID:
INSERT INTO DIM_Jour (jour_id, AAAA, MM, JJ, Jour_Semaine, Num_Semaine) VALUES (
'292a485f-a56a-4938-8f1a-bbbbbbbbbbb1',
2020,
11,
19,
4,
47
);
But it's probably a good practice to be explicit about it and perform the cast yourself
INSERT INTO DIM_Jour (jour_id, AAAA, MM, JJ, Jour_Semaine, Num_Semaine) VALUES (
'292a485f-a56a-4938-8f1a-bbbbbbbbbbb1'::UUID,
2020,
11,
19,
4,
47
);
You should use UUID generator and install UUID extension. PostgreSQL requires valid UUIDs conforming to RFC 4122. Random strings are not valid UUIDs.
Also, as it is mentioned below, you should pass your UUIDs as quoted strings.

How to simply transpose two columns into a single row in postgres?

Following is the output of my query:
key ;value
"2BxtRdkRvwc-2hPjF8LBmHD-finapril" ;4
"3QXORSfsIY0-2sDizCyvY6m-finapril" ;12
"4QXORSfsIY0-2sDizCyvY6m-curr" ;12
"5QXORSfsIY0-29Xcom4SHVh-finapril" ;12
What i want is simply to bring the rows into columns so that only one row remains with the key as the column name.
I have seen examples with crosstab catering to much complex use cases but i want to know if there is a simpler way in which this can be achieved in my particular case?
Any help is appreciated
Thanks
Postgres Version : 9.5.10
It is impossible to execute a query resulting in an unknown number and names of columns. The simplest way to get a similar effect is to generate a json object which can be easily interpreted by a client app as a pivot table, example:
with the_data(key, value) as (
values
('2BxtRdkRvwc-2hPjF8LBmHD-finapril', 4),
('3QXORSfsIY0-2sDizCyvY6m-finapril', 12),
('4QXORSfsIY0-2sDizCyvY6m-curr', 12),
('5QXORSfsIY0-29Xcom4SHVh-finapril', 12)
)
select jsonb_object_agg(key, value)
from the_data;
The query returns this json object:
{
"4QXORSfsIY0-2sDizCyvY6m-curr": 12,
"2BxtRdkRvwc-2hPjF8LBmHD-finapril": 4,
"3QXORSfsIY0-2sDizCyvY6m-finapril": 12,
"5QXORSfsIY0-29Xcom4SHVh-finapril": 12
}

How to Order By a column but array come first

(Sorry for my bad English)
I have an array of users ids as below:
[5, 9, 3, 22, 16]
Obviously the values are dynamic.
Now, I need to SELECT all users but users with above ids come first.
What I've tried so far?
This query gives me exact answer :
SELECT * FROM users WHERE id IN (5, 9, 3, 22, 16)
UNION ALL
SELECT * FROM users WHERE id NOT IN (5, 9, 3, 22, 16);
But is there any better way?
P.S:
I'm using PostgreSQL 10.
Try this:
select *
from users
order by id not in (5, 9, 3, 22, 16), id
As stated in the documentation, an expression used in the ORDER BY clause
can be an arbitrary expression formed from input-column values.
In particular, you can use a Boolean expression, as values of this type are sortable. Note that false < true.
You can use CASE statements on your ORDER BY, I'll give you an example:
select *
from users
order by
CASE WHEN id=5 THEN 1
WHEN id=9 THEN 2
WHEN id=3 THEN 3
WHEN id=22 THEN 4
WHEN id=16 THEN 5
END, id
With CASE you can tell postgres the "priority" or value you want for each id if you know them beforehand. After that I added "id" so the rest of the rows gets ordered properly.

BIRT reporting - use the same parameter multiply times in a sql query

I have this where clause:
WHERE p.ROLE = 'doctor'
AND((p6.PA_Name='Event_Day_From' AND p6.PA_Value>= SUBSTRING('01.01.2012', 1, 2))
AND (p7.PA_Name='Event_Month_From' AND p7.PA_Value>=SUBSTRING('01.01.2012', 4, 2))
AND (p8.PA_Name='Event_Year_From' AND P8.PA_Value>=SUBSTRING('01.01.2012', 7, 4)))
AND ((p9.PA_Name='Event_Day_To' AND P9.PA_Value<=SUBSTRING('30.12.2012', 1, 2))
AND (p10.PA_Name='Event_Month_To' AND P10.PA_Value<=SUBSTRING('30.12.2012', 4, 2))
AND (p11.PA_Name='Event_Year_To' AND P11.PA_Value<=SUBSTRING('30.12.2012', 7, 4)))
after the above I have an union all and at the end I have another WHERE clause exacly the same as the above.
In BIRT a parameter can be passed and you have to insert ? in the SQL query where you need it to be passed. As you can see I have a start date and an end date wich will be passed trough an user input. Now my problem is that I have no idea how to pass the SDate parameter to all the start dates and the EndDate parameter to all the end dates
Is there a solution for my problem?
I solved this problem by creating table with a single row from the parameters, and attaching it to the report query like so:
,(select ? SDate, ? EDate) params
WHERE p.ROLE = 'doctor'
AND((p6.PA_Name='Event_Day_From' AND p6.PA_Value>= SUBSTRING(params.SDate, 1, 2))
AND (p7.PA_Name='Event_Month_From' AND p7.PA_Value>=SUBSTRING(params.SDate, 4, 2))
AND (p8.PA_Name='Event_Year_From' AND P8.PA_Value>=SUBSTRING(params.SDate, 7, 4)))
AND ((p9.PA_Name='Event_Day_To' AND P9.PA_Value<=SUBSTRING(params.EDate, 1, 2))
AND (p10.PA_Name='Event_Month_To' AND P10.PA_Value<=SUBSTRING(params.EDate, 4, 2))
AND (p11.PA_Name='Event_Year_To' AND P11.PA_Value<=SUBSTRING(params.EDate, 7, 4)))
Hope this helps.
**I use this method on a PostgreSQL database currently.
[EDIT] BIRT uses plain JDBC not it's not supporting "named parameters", so you can't write:
... p6.PA_Value>= SUBSTRING(:start, 1, 2) ...
This will give an error.
Other options are to build the query using Property Binding or JavaScript and replace parts of it before it is executed. See this example report
Some databases also support the WITH syntax to assign an alias to a ? parameter. This blog post explains how to use this.

Problem converting nvarchar to decimal t-sql

I'm trying to convert nvarchar to decimal (18,2) and I'm receiving the following message:
Msg 8115, Level 16, State 6, Line 2
Arithmetic overflow error converting nvarchar to data type numeric.
The CAST is: CAST(bm_onnet AS decimal(18,2)) as bm_onnet_corr,
it works only if the value has only maximum 3 decimals, doesn't work for value below:
21.8333333333333333333333333333333333333
How should I modify my SELECT?
Use the round function
example
declare #v nvarchar(100) = '21.8333333333333333333333333333333333333'
select convert(decimal(18,2),round(#v,2))
a select would look like this
SELECT CAST(round(bm_onnet,2) AS decimal(18,2)) as bm_onnet_corr
select
case when charindex('.',bm_onnet)) > = 2 then
convert(decimal(18,2),substring(bm_onnet,0,charindex('.',bm_onnet)+3))
else
convert(decimal(18,2),bm_onnet)
end
too early in the morning use this instead.