Xpath query - Fields showing null - xpath

SQL Server 2008 R2
I have the following CTE and XPath query that I'm having an issue with.
IF OBJECT_ID('tempdb..#TempXML') IS NOT NULL
DROP TABLE #TempXML;
WITH ConvertedToXML AS
(
SELECT top 500 xml_msg AsVarchar
,status [status]
,date_received
,CAST(xml_msg AS XML) AS AsXml
FROM interface_master_out
order by date_received desc
)
SELECT
ConvertedToXML.AsXml.value('(//InstrumentID)[1]', 'varchar(max)') AS InstrumentID
,ConvertedToXML.AsXml.value('(//MessageType)[1]', 'Varchar(10)') as MessageType
,ConvertedToXML.AsXml.value('(//MessageID)[1]', 'Varchar(10)') as MessageID
,ConvertedToXML.AsXml.value('(//date_received)[1]', 'datetime') as date_received
,ConvertedToXML.AsXml.value('(//status)[1]', 'Varchar(10)') as [Status]
,ConvertedToXML.AsVarchar
,ConvertedToXML.AsXml
Into #TempXML
FROM ConvertedToXML
where ConvertedToXML.AsXml.value('(//InstrumentID)[1]', 'varchar(max)') in ('BA1254890001');
select * from #TempXML
drop table #TempXML
date_received and Status are both coming up null and I can't figure out why. I've paired down the in ( ) to a single value but there are really 30 of them.

Once I played around with this enough, I was actually ridiculously easy. Below is the revised and working code:
Use MyDatabase
IF OBJECT_ID('tempdb..#TempXML') IS NOT NULL
DROP TABLE #TempXML;
WITH ConvertedToXML AS
(
SELECT top 50 xml_msg AsVarchar
,status Status
,date_received DateTime
,CAST(xml_msg AS XML) AS AsXml
FROM interface_master_out
order by date_received desc
)
SELECT
ConvertedToXML.AsXml.value('(//InstrumentID)[1]', 'varchar(max)') AS InstrumentID
,ConvertedToXML.AsXml.value('(//MessageType)[1]', 'Varchar(10)') as MessageType
,ConvertedToXML.AsXml.value('(//MessageID)[1]', 'Varchar(10)') as MessageID
,ConvertedToXML.Status
,ConvertedToXML.DateTime
,ConvertedToXML.AsVarchar
,ConvertedToXML.AsXml
Into #TempXML
FROM ConvertedToXML
where ConvertedToXML.AsXml.value('(//InstrumentID)[1]', 'varchar(max)') = ('BA1254890001')
select * from #TempXML
drop table #TempXML

Related

How to modify column data-type while column is in used

I have problem while I use SELECT query. Unfortunettly, the ID is store as VARCHAR which is big mistake and right now I have problem in following function
FUNCTION GET_SUB_PROJECTS(p_currentUserId IN VARCHAR,p_projectId IN INT)
RETURN SYS_REFCURSOR IS
rc SYS_REFCURSOR;
-- getSubProject
BEGIN
OPEN rc FOR
SELECT
p.*,
a.number_ AS activityNumber,
a.description AS activityDescription
FROM
projects p
LEFT JOIN
project_users_schedule_dates pusd
ON
pusd.ProjectID = p.ProjectID AND pusd.UserID = p_currentUserId
LEFT JOIN
activities a
ON
a.id = p.activity
LEFT JOIN
responsible_persons rp
ON
rp.ProjectID = p.ProjectID AND rp.UserID = p_currentUserId
LEFT JOIN
users u
ON
u.UserID = p_currentUserId
WHERE
(u.User_roleID = 1 AND
p.CustomName LIKE CONCAT((SELECT CustomName FROM projects pr WHERE pr.ProjectID = p_projectId), '%') AND p.ProjectID <> p_projectId)
OR
((
(p.Responsible_person_id = p_currentUserId OR p.Delivery_contact = p_currentUserId OR rp.UserID = p_currentUserId OR (pusd.UserID = p_currentUserId AND SYSTIMESTAMP BETWEEN TO_DATE(pusd.StartDate,'YYYY-MM-DD') AND TO_DATE(pusd.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY AND
SYSTIMESTAMP BETWEEN TO_DATE(p.StartDate,'YYYY-MM-DD') AND TO_DATE(p.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY))
)
AND
p.CustomName LIKE CONCAT((SELECT CustomName FROM projects pr WHERE pr.ProjectID = p_projectId), '%') AND p.ProjectID <> p_projectId)
ORDER BY p.CustomName;
RETURN rc;
END GET_SUB_PROJECTS;
When I call function it needs to return data, but it doesn't. Somehow, here p.Responsible_person_id and p.Delivery_contact needs to be NUMBER but somehow it is VARCHAR
When I call function I use
SELECT PROJECT_PACKAGE.GET_SUB_PROJECTS('199',141) FROM DUAL
I found one solution to modify but It throw me error like
Error report -
ORA-01439: column to be modified must be empty to change datatype
01439. 00000 - "column to be modified must be empty to change datatype"
What to do in this situation ? What is the best method to solve this issue ?
You can change the data type of a column online using dbms_redefinition
create table t (
c1 varchar2(10)
primary key
);
create table t_new (
c1 number(10, 0)
primary key
);
insert into t values ( '1.0000' );
commit;
begin
dbms_redefinition.start_redef_table (
user, 't', 't_new',
col_mapping => 'to_number ( c1 ) c1',
options_flag => dbms_redefinition.cons_use_rowid
);
end;
/
exec dbms_redefinition.sync_interim_table ( user, 't', 't_new' );
exec dbms_redefinition.finish_redef_table ( user, 't', 't_new' );
desc t
Name Null? Type
C1 NOT NULL NUMBER(10)
select * from t;
C1
1
There are also options to copy constraints, triggers, indexes, etc. automatically in this process.

Column name is not passed to PostgreSQL on JDBC Scan in Apache Drill

While trying to run SQL query for PostgreSQL, instead of the column names from the table referred it it pushing down * to the database.
select
m.m_id,
cnt_c_no
from (
select
m_id
from pg_test_main.test1.table1
where
last_date >= '2019-01-01 00:00:00'
) as m
left join (
select
ci.m_id,
count(ci.c_no) as cnt_c_no
from (
select
m_id,
c_no
from pg_test.public.table2
) as ci
inner join (
select
c_no
from pg_test.public.table3
where
is_del = 'F'
) as c on ci.c_no = c.c_no
group by
ci.m_id
) as join1 on m.m_id = join1.m_id;
00-00 Screen
00-01 Project(m_id=[$0], cnt_c_no=[$1])
00-02 Project(m_id=[$0], cnt_c_no=[$2])
00-03 HashJoin(condition=[=($0, $1)], joinType=[left], semi-join: =[false])
00-05 Jdbc(sql=[SELECT "m_id" FROM "test1"."table1" WHERE "last_date" >= '2019-01-01 00:00:00' ])
00-04 Project(m_id0=[$0], cnt_c_no=[$1])
00-06 HashAgg(group=[{0}], cnt_c_no=[COUNT($1)])
00-07 Project(m_id=[$0], c_no=[$1])
00-08 HashJoin(condition=[=($1, $2)], joinType=[inner], semi-join: =[false])
00-10 Project(m_id=[$3], c_no=[$1])
00-12 Jdbc(sql=[SELECT * FROM "public"."table2" ])
00-09 Project(c_no0=[$0])
00-11 Project(c_no=[$0])
00-13 SelectionVectorRemover
00-14 Filter(condition=[=($60, 'F')])
00-15 Jdbc(sql=[SELECT * FROM "public"."table3" ])
As you can see, Jdbc Scan for table1 was using column names.
but, Jdbc Scan for table2 and table3 was not using column names. It pushed down * to the database.
How can I control jdbc scan so that it can push down colume names?
Apache Drill version is 1.16.0 (embedded-mode)
I tried to reproduce it with MySQL on both Drill 1.17 and Drill 1.15, but for the query, similar to the query you have specified, all the query is pushed into the JDBC storage:
SELECT m.person_id,
cnt_c_no
FROM
(SELECT person_id
FROM mysql.`drill_mysql_test1`.person1
WHERE date_field >= '2019-01-01 00:00:00') AS m
LEFT JOIN
(SELECT ci.person_id,
count(ci.last_name) AS cnt_c_no
FROM
(SELECT person_id,
last_name
FROM mysql.`drill_mysql_test`.person) AS ci
INNER JOIN
(SELECT last_name
FROM mysql.`drill_mysql_test`.person2
WHERE boolean_field = 'F' ) AS c ON ci.last_name = c.last_name
GROUP BY ci.person_id) AS join1 ON m.person_id = join1.person_id
The plan for this query:
00-00 Screen
00-01 Project(person_id=[$0], cnt_c_no=[$1])
00-02 Jdbc(sql=[SELECT `t0`.`person_id`, `t5`.`cnt_c_no` FROM (SELECT `person_id` FROM `drill_mysql_test1`.`person1` WHERE `date_field` >= '2019-01-01 00:00:00') AS `t0` LEFT JOIN (SELECT `t1`.`person_id`, COUNT(`t1`.`last_name`) AS `cnt_c_no` FROM (SELECT `person_id`, `last_name` FROM `drill_mysql_test`.`person`) AS `t1` INNER JOIN (SELECT `last_name` FROM `drill_mysql_test`.`person2` WHERE `boolean_field` = 'F') AS `t3` ON `t1`.`last_name` = `t3`.`last_name` GROUP BY `t1`.`person_id`) AS `t5` ON `t0`.`person_id` = `t5`.`person_id` ])
Could you please provide CTAS for Postgres tables, so I will try to reproduce it again with specific data types. Also, if possible, please check whether this issue is still reproduced on Drill 1.17.
UPD:
Comment under this answer helped to discover that this problem was caused by the following issue: https://issues.apache.org/jira/browse/DRILL-7340 and it will be resolved in Drill 1.18.0.

How to pass all in between dates from date range in "IN" operator for Oracle Pivot?

What I want is to pass a complete range of dates in the Pivot "IN" clause. But what i am doing is that using the values only that i am getting from database.
For ex.
Suppose if user select the From date as '10/10/2015' and To date as '10/15/2015' then I want to use all the values (10/10/2015,10/11/2015,10/12/2015,10/13/2015,10/14/2015,10/15/2015)
But what is happening from my query is ('10/10/2015','10/15'2015').
SELECT * FROM
(
SELECT
Employee.M_NAME AS MANAGER_NAME,
Employee.PHONE,
Employee.JOB_ID,
Employee.Assigned_DATE,
Employee.SHIFT,
Employee.Dept as Assignment,
Employee.E_ID,
Employee.NAME AS EMP_NAME,
Employee.DEPT_COLOR
FROM Employee
WHERE Assigned_Date BETWEEN
TO_DATE('FD_Selected','MM/DD/YYYY') AND
TO_DATE('TD_Selected','MM/DD/YYYY')
ORDER by Employee.E_ID
) x
PIVOT
(
min(Assignment)
FOR Assigned_Date IN (TO_DATE('FD_Selected','YYYY-MM-DD'),
TO_DATE('TD_Selected','YYYY-MM-DD')
)
) p
Now the data is coming like this:
M_NAME PHONE JOB_ID Assigned_DATE SHIFT Assignment E_ID EMP_NAME DEPT_COLOR '10/10/2015' '10/15/2015'
But I want like this:
M_NAME PHONE JOB_ID Assigned_DATE SHIFT Assignment E_ID EMP_NAME DEPT_COLOR '10/10/2015' '10/11/2015' '10/12/2015' '10/13/2015' '10/14/2015' '10/15/2015'

Oracle procedure 'with query' insert into table

I have created an Oracle SQL query in TOAD which works fine. I now need to put this in a procedure.
The query has to create two counts based on different criteria (I have used With Select) and insert these plus a date and location to a table.
The query that works is
with
Selected_animals as
( SELECT TO_CHAR(SYSDATE,'DD/MM/YYYY' ) as Report_Date,
loc.name location,
count(rran.id) as Count_exported
FROM rr_animals rran,
contact con,
locations loc,
names nam
WHERE con.connum = rran.connum
AND con.loc_id = loc.id
AND con.connum = nam.connum
AND nam.name_type = 'STAND'
AND nam.dob IS NOT NULL
AND rran.sex IS NOT NULL
AND rran.web_display = 'Y'
AND rran.web_description IS NOT NULL
AND rran.visit_end_date IS NULL
AND con.loc_id IS NOT NULL
AND con.datedl IS NULL
AND rran.hold_user IS NULL
AND rran.assess_status IS NULL
AND EXISTS (SELECT rrim.id
FROM rr_images rrim
WHERE rrim.image_type = 'KENNEL'
AND rrim.rran_id = rran.id
AND DBMS_LOB.GETLENGTH(rrim.image_object) >0
AND rrim.image_object IS NOT NULL)
group by loc.NAME ),
total_animals as
(select vbav.sitename as location,
count(vbav.rran_ID) as Count_available
from v_bx_all_animal_visits vbav
where visit_end_date is null
and concat != 'DELTD'
and concat != 'DSCD'
group by vbav.sitename)
select Total_animals.location,
Selected_animals.Report_date,
Selected_animals.count_exported,
Total_animals.count_available
from Selected_animals, total_animals
where total_animals.location = selected_animals.location(+)
I have looked at several ways that seem to write the procedure but nothing seems to work. Including which was added under the CREATE or REPLACE and before BEGIN:
( o_location out bx_webstats_export_available.LOCATION%TYPE,
o_date out bx_webstats_export_available.REPORT_DATE%TYPE,
o_exported out bx_webstats_export_available.COUNT_EXPORTED%TYPE,
o_available out bx_webstats_export_available.COUNT_AVAILABLE%TYPE )
Also added after the last where statement and before End:
INSERT INTO bx_webstats_export_available(location, report_date, count_export, count_available)
values (Total_animals.location,
Selected_animals.Report_date,
Selected_animals.count_exported,
Total_animals.count_available);
Can anyone help me get this query in a Procedure please?
This is the first time I have written a Procedure from scratch and I'm struggling with it.
Many thanks,
What is it you're trying to do? Insert the results of that select into a table? If so, the following ought to suffice:
create or replace procedure your_proc_name
as
begin
insert into bx_webstats_export_available(location, report_date, count_export, count_available)
with selected_animals as (select to_char(sysdate,'DD/MM/YYYY' ) as report_date,
loc.name location,
count(rran.id) as count_exported
from rr_animals rran,
contact con,
locations loc,
names nam
where con.connum = rran.connum
and con.loc_id = loc.id
and con.connum = nam.connum
and nam.name_type = 'STAND'
and nam.dob is not null
and rran.sex is not null
and rran.web_display = 'Y'
and rran.web_description is not null
and rran.visit_end_date is null
and con.loc_id is not null
and con.datedl is null
and rran.hold_user is null
and rran.assess_status is null
and exists (select rrim.id
from rr_images rrim
where rrim.image_type = 'KENNEL'
and rrim.rran_id = rran.id
and dbms_lob.getlength(rrim.image_object) >0
and rrim.image_object is not null)
group by loc.name),
total_animals as (select vbav.sitename as location,
count(vbav.rran_id) as count_available
from v_bx_all_animal_visits vbav
where visit_end_date is null
and concat != 'DELTD'
and concat != 'DSCD'
group by vbav.sitename)
select total_animals.location,
selected_animals.report_date,
selected_animals.count_exported,
total_animals.count_available
from selected_animals, total_animals
where total_animals.location = selected_animals.location(+);
end your_proc_name;
/
If not, then please explain a bit more about the requirements you're trying to satisfy.

Linq and sorting null fields

I have a table that has (for example) 4 columns.
pk_table_id INT NOT NULL
username VARCHAR(100) NOT NULL
start_date DATETIME NOT NULL
end_date DATETIME NULL
My requirement is to return all rows in descending order of end_date - BUT the NULL values must be first, and then descending order of start_date.
I've done it in SQL - but could someone assist me with a LINQ version to do this?
This is the SQL query we use:
SELECT [person_employment_id]
, [party_id]
, [employer_name]
, [occupation]
, [telephone]
, [start_date]
, [end_date]
, [person_employment_type_id]
, [person_employment_end_reason_type_id]
, [comments]
, [deleted]
, [create_user]
, [create_date]
, [last_update_user]
, [last_update_date]
, [version]
FROM [dbo].[person_employment]
WHERE ([party_id]=#party_id)
ORDER BY ISNull([end_date],'9999-DEC-31') DESC, [start_date] DESC
For this problem, you could do a null check on the end_date and use that result as the ordering. So you don't need to use the same SQL constructs to achieve this, but rather use one more natural in your language of choice (C# I'm assuming).
var query =
from row in dc.Table
let isEndDateNull = row.end_date == null
orderby isEndDateNull descending, row.start_date descending
select row;

Resources