SQL - insert into from one table to another but manipulate data - sql

I am trying to copy data from one table to another by using the following script:
insert into test_report
( company_id
, report_id
, brch_code
, definition
, description
, editable_flag
, executable_flag
, name
, report_type )
values
( 2420
, 'RP00002004'
, '0001'
, (select definition from test_template_report where template_id='RP00001242')
, (select description from test_template_report where template_id='RP00001242')
, (select editable_flag from test_template_report where template_id='RP00001242')
, (select executable_flag from test_template_report where template_id='RP00001242')
, (select name from test_template_report where template_id='RP00001242')
, '01' );
This is working fine, but the definition field contains XML which would need to be modified slightly.
The following is part of the definition data:
<listdef page='25'><reportId>RP00000390</reportId><name>Fund Transfer</name><description>Fund Transfer</description>
The <reportId>RP00000390</reportId> part would need to be changed to be RP00002004 as per the insert into script.
Like the following:
<listdef page='25'><reportId>RP00002004</reportId><name>Fund Transfer</name><description>Fund Transfer</description>
Is this possible?

You can use XMLQuery with a modify ... replace value of node:
insert into test_report (company_id,report_id,brch_code,definition,description,
editable_flag,executable_flag,name,report_type)
select 2420, 'RP00002004', '0001',
XMLQuery('copy $i := $d modify
(for $j in $i//reportId return replace value of node $j with $r)
return $i'
passing definition as "d", 'RP00002004' as "r"
returning content),
description, editable_flag, executable_flag, name, '01'
from test_template_report where template_id='RP00001242';
You don't need all the individual selects from the template table, a single insert-select will do.
The XML manipulation assumes definition is an XMLType; if it isn't you can convert it to one in the passing clause, i.e. passing XMLType(definition) as "d". The value of the reportId node (or nodes) is replaced with the string passed as "r".
As a quick static demo of that replacement happening, with the XML supplied in-line as a string literal:
select
XMLQuery('copy $i := $d modify
(for $j in $i//reportId return replace value of node $j with $r)
return $i'
passing XMLType(q'[<listdef page='25'><reportId>RP00000390</reportId><name>Fund Transfer</name><description>Fund Transfer</description></listdef>]') as "d",
'RP00002004' as "r"
returning content)
as modified_definition
from dual;
MODIFIED_DEFINITION
------------------------------------------------------------------------------------------------------------------------------
<listdef page="25"><reportId>RP00002004</reportId><name>Fund Transfer</name><description>Fund Transfer</description></listdef>
Read more.

The replace function replaces one text string with another, so you could change
definition
to
replace(definition, '<reportId>RP00000390</reportId>', '<reportId>RP00002004</reportId>')
You can also get all the columns you need from test_template_report in one go:
insert into test_report
( company_id
, report_id
, brch_code
, definition
, description
, editable_flag
, executable_flag
, name
, report_type )
select 2420
, 'RP00002004'
, '0001'
, replace(tr.definition, '<reportId>RP00000390</reportId>', '<reportId>RP00002004</reportId>')
, tr.description
, tr.editable_flag
, tr.executable_flag
, tr.name
, '01'
from test_template_report tr
where tr.template_id = 'RP00001242';
If you wanted to replace any value of reportIf and not just 'RP00000390', you could use regexp_replace:
insert into test_report
( company_id
, report_id
, brch_code
, definition
, description
, editable_flag
, executable_flag
, name
, report_type )
select 2420
, 'RP00002004'
, '0001'
, regexp_replace(definition,'<reportId>[^<]+</reportId>','<reportId>RP00002004</reportId>')
, tr.description
, tr.editable_flag
, tr.executable_flag
, tr.name
, '01'
from test_template_report tr
where tr.template_id = 'RP00001242';

Related

T-SQL - Save query with XML output including namespace into table or variable

I would like to save the output from the query below into a variable or a table.
However it gives an error because the query starts with "With namespace ..."
WITH XMLNAMESPACES (
'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2' as cac
, 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2' as cbc
)
select
'123456''cbc:ID'
, '20222903' 'cbc:IssueDate'
, 'Supplier name' 'cac:AccountingSupplierParty/cac:Party/cac:PartyName/cbc:Name'
, ( select
'1' 'cac:Line'
, '3' 'cac:Quantity'
, '120.80' 'cac:LineTotal'
, '8594' 'cac:ItemCode'
for xml path ('cac:InvoiceLine' ) , type
)
for xml path ('') , type , root ('Invoice') ;
I tried to store into an variable like:
declare #content xml = WITH XMLNAMESPACES ......... ;
And I also tried to insert into a table.
You should assign an expression, use brackets around the select
declare #x xml;
WITH XMLNAMESPACES (
'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2' as cac
, 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2' as cbc
)
select #x= (select
'123456''cbc:ID'
, '20222903' 'cbc:IssueDate'
, 'Supplier name' 'cac:AccountingSupplierParty/cac:Party/cac:PartyName/cbc:Name'
, ( select
'1' 'cac:Line'
, '3' 'cac:Quantity'
, '120.80' 'cac:LineTotal'
, '8594' 'cac:ItemCode'
for xml path ('cac:InvoiceLine' ) , type
)
for xml path ('') , type , root ('Invoice')
);
select #x;

Oracle SQL Loader discarding data and showing NULL values ins

I have this issue with SQLLoader. I am working with a dataset with 99 columns. Everything is being loaded to a VARCHAR2(500 BYTE) - I went through the data manually to make sure there was enough space in each column.
CSV Properties
Comma delimited
Line terminated by CRLF
Text Qualifier '"'
The issue is, when I load the data manually (I use Toad for Oracle) - the data appears just fine. However, using my SQLLoader - it "successfully" loads all the data however when you query the table, the table has all the rows but all the data is missing. (Null values appear) - Can anyone help with this?
This is the ctl file code:
OPTIONS (direct=true)
LOAD DATA
INFILE 'C:\Paths\DATA_PRCS\MarketData\FitchRatings\DBUpload\test.csv'
DISCARDFILE 'C:\Paths\DATA_PRCS\MarketData\FitchRatings\DBUploadProcess\ErrorFiles\FitchIssue_Errors.csv'
TRUNCATE INTO TABLE MARKETDATA.PRLD_FITCH_ISSUE_DATA
fields terminated by "," OPTIONALLY ENCLOSED BY '"' trailing nullcols
(
REPORT_DATE_TIME
, AGENT_COMMON_ID
, AGENT_CUSIP
, AGENT_LEI
, CUSTOMER_IDENTIFIER
, MARKET_SECTOR_ID
, COUNTRY_NAME
, ISSUER_ID
, ISSUER_NAME
, ISSUE_RECORD_CHANGE_CODE_DATE
, FITCH_ISSUE_ID_NUMBER
, COUNTRY_CODE
, STATE_PROVINCE
, CUSIP_IDENTIFIER
, ISIN_IDENTIFIER
, ISMA_IDENTIFIER
, LOANX_ID
, COMMON_NUMBER
, WERTPAPIER_IDENTIFIER
, RECORD_GROUP_TYPE_CODE
, ISSUE_DEBT_LEVEL_CODE
, CLASS_TYPE
, ISSUE_DESCRIPTION
, ISSUE_MATURITY_DATE
, ISSUE_TRANCHE_SERIES
, ISSUE_CLASS
, ISSUE_CURRENCY_CODE
, ISSUE_AMOUNT
, ISSUE_COUPON_TYPE
, ISSUE_COUPON_FIXED_RATE
, ISSUE_COUP_NON_FIXED_RATE_DESC
, ISSUE_COUPON_INDEX_DESCRIPTION
, ISSUE_COUPON_SPREAD
, ISSUE_COUPON_CAPPED_RATE
, ENHANCEMENT_TYPE
, ENHANCEMENT_PROVIDER
, PROJECT
, PRIVATE_PLACEMENT_144A_CODE
, US_FED_TAX_EXEMPT_STATUS_CODE
, ISSUE_RECORD_CHANGE_CODE
, LT_ISSUE_RATING
, LT_ISSUE_RATING_ACTION
, LT_ISSUE_RATING_EFFECTIVE_DATE
, LT_ISSUE_RATING_ALERT_CODE
, LT_ISSUE_RATING_SOL_STATUS
, ISSUE_RECOVERY_RATING
, ISSUE_DISTRESSED_RECOV_RATING
, UNENHANCED_LT_ISSUE_RATING
, UNENHANCED_LTR_ACTION
, UNENHANCED_LTR_EFFECTIVE_DATE
, UNENHANCED_LTR_ALERT_CODE
, UNENHANCED_LTR_SOL_STATUS
, LT_NATIONAL_ISSUE_RATING
, LT_NATIONAL_RATING_ACTION
, LT_NATL_RATING_EFFECTIVE_DATE
, LT_NATIONAL_RATING_ALERT_CODE
, LT_NATIONAL_RATING_SOL_STATUS
, ST_ISSUE_RATING
, ST_ISSUE_RATING_ACTION
, ST_ISSUE_RATING_EFFECTIVE_DATE
, ST_ISSUE_RATING_ALERT_CODE
, ST_ISSUE_RATING_SOL_STATUS
, UNENHANCED_ST_ISSUE_RATING
, UNENHANCED_STR_ACTION
, UNENHANCED_STR_EFFECTIVE_DATE
, UNENHANCED_STR_ALERT_CODE
, UNENHANCED_STR_SOL_STATUS
, ST_NATIONAL_ISSUE_RATING
, ST_NATIONAL_RATING_ACTION
, ST_NATL_RATING_EFFECTIVE_DATE
, ST_NATIONAL_RATING_ALERT_CODE
, ST_NATIONAL_RATING_SOL_STATUS
, ENHANCED_LTR
, ENHANCED_LTR_ACTION
, ENHANCED_LTR_EFFECTIVE_DATE
, ENHANCED_LTR_ALERT_CODE
, ENHANCED_LTR_SOL_STATUS
, ENHANCED_STR
, ENHANCED_STR_ACTION
, ENHANCED_STR_EFFECTIVE_DATE
, ENHANCED_STR_ALERT_CODE
, ENHANCED_STR_SOL_STATUS
, SECURITY_IDENTIFIER_TYPE
, ENDORSEMENT_COMPLIANCE
, RATINGS_SUFFIX
, CLO_SECTOR
, CLO_INDUSTRY
, ALTERNATE_CUSIP
, ALTERNATE_ISIN
, DATA_ENTRY_TIMESTAMP expression "(select SYSDATE from dual)"
)
Rather simple in the end. The most important thing to realize was that the file was using Unicode characters. You have to specify in the ctl file CHARACTERSET UT16 in this example. Thank for trying to help all!
load data CHARACTERSET UTF8 TRUNCATE INTO TABLE "GLOBALIZATIONRESOURCE" FIELDS TERMINATED BY "," OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS

Having Trouble with FOR XML Path - No Concatenating

I have a situation where an order can contain multiple license purchases - and if the order does contain multiple licenses, I want to display the license descriptions in a single cell with the values separated by commas. If we were on SQL 2017, I could use STRING_AGG but we are on SQL 2016 so I am trying the tried and true STUFF / FOR XML Path method.
From the screenshot below, Customer 4341073 had two license purchases on Order ID 18519173:
When I add the STUFF / FOR XML Path to the T-SQL, I am not able to achieve the desired result of showing the license description in the same record - each license still has it's own row.
SELECT x.CustomerID ,
x.ATOLicenseTypeID ,
x.ATOLicense ,
x.AuthorizationBeginDate ,
x.AuthorizationEndDate ,
x.OrderID ,
x.OrderDate ,
STUFF ( (
SELECT ',' + lt.description
FROM dbo.LicenseTypes AS lt
--INNER JOIN #XMLPATH ON lt.id = x.OrderLicenseTypeID
WHERE lt.id = x.OrderLicenseTypeID
--GROUP BY ',' + lt.description
FOR XML PATH ( '' )
) , 1 , 1 , '' ) AS Licenses
FROM #XMLPATH AS x
--GROUP BY x.CustomerID ,
-- x.ATOLicenseTypeID ,
-- x.ATOLicense ,
-- x.AuthorizationBeginDate ,
-- x.AuthorizationEndDate ,
-- x.OrderID ,
-- x.OrderDate ,
-- x.OrderLicenseTypeID;
I've tried different ways to join the sub-query to the outer query and added and removed GROUP BY to achieve the desired result but nothing is working for me.
Any suggestions on where I am going wrong with this query?
Sample dataset:
DROP TABLE IF EXISTS #XMLPATH;
CREATE TABLE #XMLPATH
(
CustomerID INT ,
ATOLicenseTypeID INT ,
ATOLicense VARCHAR (500) ,
AuthorizationBeginDate DATE ,
AuthorizationEndDate DATE ,
OrderID INT ,
OrderDate DATETIME ,
OrderLicenseTypeID INT
);
INSERT INTO #XMLPATH
VALUES ( 4341073, 52, 'Temporary Resident Fishing', N'2019-01-07T00:00:00', N'2019-01-07T00:00:00', 18519136, N'2019-01-07T12:01:55.317', 2141 ) ,
( 4341073, 52, 'Temporary Resident Fishing', N'2019-01-07T00:00:00', N'2019-01-07T00:00:00', 18519173, N'2019-01-07T12:34:13.107', 204 ) ,
( 4341073, 52, 'Temporary Resident Fishing', N'2019-01-07T00:00:00', N'2019-01-07T00:00:00', 18519173, N'2019-01-07T12:34:13.107', 2141 );
SELECT * FROM #XMLPATH;
SELECT x.CustomerID ,
x.ATOLicenseTypeID ,
x.ATOLicense ,
x.AuthorizationBeginDate ,
x.AuthorizationEndDate ,
x.OrderID ,
x.OrderDate ,
STUFF ( (
SELECT ',' + lt.description
FROM dbo.LicenseTypes AS lt
--INNER JOIN #XMLPATH ON lt.id = x.OrderLicenseTypeID
WHERE lt.id = x.OrderLicenseTypeID
--GROUP BY ',' + lt.description
FOR XML PATH ( '' )
) , 1 , 1 , '' ) AS Licenses
FROM #XMLPATH AS x
GROUP BY x.CustomerID ,
x.ATOLicenseTypeID ,
x.ATOLicense ,
x.AuthorizationBeginDate ,
x.AuthorizationEndDate ,
x.OrderID ,
x.OrderDate ,
x.OrderLicenseTypeID;
In order to get all rows of one OrderID as one result-row, you must not include the separating information (the OrderLicenseTypeID) into the GROUP BY. But then you have the issue you've encountered: You cannot use this ID within your FOR XML construct.
The trick is (as your out-commented trials show), to add the source table to the sub-select and filter there with a grouped column. But you have to use different aliases to deal with them as two different sets. Try this:
(I had to add one more temp table to test this...)
SELECT x.CustomerID ,
x.ATOLicenseTypeID ,
x.ATOLicense ,
x.AuthorizationBeginDate ,
x.AuthorizationEndDate ,
x.OrderID ,
x.OrderDate ,
STUFF ( (
SELECT ',' + lt.description
FROM #XMLPATH x2
INNER JOIN #LicenseTypes AS lt ON lt.id=x2.OrderLicenseTypeID
WHERE x2.OrderID = x.OrderID --you might need to add more columns here....
--in most cases we want to add an ORDER BY
FOR XML PATH ( '' )
) , 1 , 1 , '' ) AS Licenses
FROM #XMLPATH AS x
GROUP BY x.CustomerID ,
x.ATOLicenseTypeID ,
x.ATOLicense ,
x.AuthorizationBeginDate ,
x.AuthorizationEndDate ,
x.OrderID ,
x.OrderDate;
Btw: Starting with v2017 there is STRING_AGG(), which makes this much easier...

SQL Pivot Issue

If you could please help with this. The code generates an error:
Msg 8156, Level 16, State 1, Line 236
The column 'Classification_Value_Id' was specified multiple times for 'piv1'.
I am doing this on SQL Server. The steps for the code is as follows:
1. Unpivot the data from the source table DB.[dbo].[Classification] into one column
2. Join this unpivoted data to a table called DB.dbo.[Classification_Value] to return/add the column 'cv.Classification_Name' to the data set
3. Pivot this dataset (This is the part returning the error)
CODE:
SELECT
activityCode
, actjvPartnerRef
, actMonth
, actSalesChannel
, addCBPCharge
, agentId
, appType
, areaCode
--SELECT
--polRef,[Arrangement_Id],UnpivotedData.Classification_Value_Id,UnpivotedData.Classification_Scheme_Id,ColValues, ColNames,cv.Classification_Name
FROM
(
SELECT top 10
[polRef]
, [Arrangement_Id]
, [Classification_Scheme_Id]
, [Classification_Value_Id]
-- ,[Arrangement_Classification_Type_Id]
-- ,[Effective_TimeStamp]
-- ,[End_date]
, CAST((ISNULL([character_measure],'')) AS NVARCHAR(MAX)) AS character_measure
, CAST((ISNULL([datetime_measure],'')) AS NVARCHAR(MAX)) AS datetime_measure
, CAST([decimal_measure] AS NVARCHAR(MAX)) AS decimal_measure
, CAST((ISNULL([integer_measure],'')) AS NVARCHAR(MAX)) AS integer_measure
, CAST((ISNULL([logical_measure],'')) AS NVARCHAR(MAX)) AS logical_measure
, CAST((ISNULL([charmax_measure],'')) AS NVARCHAR(MAX)) AS charmax_measure
, CAST((ISNULL([long_measure],'')) AS NVARCHAR(MAX)) AS long_measure
FROM DB.[dbo].[Classification]
) AS SrcDataConverted
UNPIVOT
(
ColValues FOR ColNames IN
(
character_measure
, datetime_measure
, decimal_measure
, integer_measure
, logical_measure
, charmax_measure
, long_measure
)
) AS UnpivotedData
LEFT JOIN DB.dbo.[Classification_Value] cv
ON cv.[Classification_Scheme_Id] = UnpivotedData.[Classification_Scheme_Id]
AND cv.Classification_Value_Id = UnpivotedData.Classification_Value_Id
PIVOT
(MAX(ColValues) for Classification_Name in (
activityCode
, actjvPartnerRef
, actMonth
, actSalesChannel
, addCBPCharge
, agentId
, appType
, areaCode
)) AS piv1;
Any help would be much appreciated
Thank you
StuarLC:
An additional derived table needs to wrap the results of the UNPIVOT before commencing the re-PIVOT, as the join introduces a duplicated Classification_Value_Id and Classification_Scheme_id, which is needed for the join.
select
activityCode
, actjvPartnerRef
, actMonth
, actSalesChannel
, addCBPCharge
, agentId
, appType
, areaCode
from (
SELECT polRef
, [Arrangement_Id]
, UnpivotedData.Classification_Value_Id
, UnpivotedData.Classification_Scheme_Id
, ColValues
, ColNames
, Classification_Name
FROM (
SELECT [polRef]
, [Arrangement_Id]
, [Classification_Scheme_Id]
, [Classification_Value_Id]
, CAST((ISNULL([character_measure],'')) AS NVARCHAR(MAX)) AS character_measure
, CAST((ISNULL([datetime_measure],'')) AS NVARCHAR(MAX)) AS datetime_measure
, CAST([decimal_measure] AS NVARCHAR(MAX)) AS decimal_measure
, CAST((ISNULL([integer_measure],'')) AS NVARCHAR(MAX)) AS integer_measure
, CAST((ISNULL([logical_measure],'')) AS NVARCHAR(MAX)) AS logical_measure
, CAST((ISNULL([charmax_measure],'')) AS NVARCHAR(MAX)) AS charmax_measure
, CAST((ISNULL([long_measure],'')) AS NVARCHAR(MAX)) AS long_measure
FROM DB.[dbo].[Classification]
) AS SrcDataConverted
UNPIVOT
(
ColValues FOR ColNames IN
(
character_measure
, datetime_measure
, decimal_measure
, integer_measure
, logical_measure
, charmax_measure
, long_measure
)
) AS UnpivotedData
LEFT JOIN
DB.dbo.[Classification_Value] cv
ON cv.[Classification_Scheme_Id] = UnpivotedData.[Classification_Scheme_Id]
AND cv.Classification_Value_Id = UnpivotedData.Classification_Value_Id
) as src
PIVOT
(
MAX(ColValues) for Classification_Name in (
activityCode
, actjvPartnerRef
, actMonth
, actSalesChannel
, addCBPCharge
, agentId
, appType
, areaCode
)
) AS piv1;

Getting MAX Value of a Field for INSERT Statement

I am trying to insert a new record in a small settings table and I would like to get the MAX value of the DisplayOrder field and add 10 to it. I get errors with the MAX function in the value of the insert.
INSERT INTO tMrMenu
([ParentId]
,[DisplayOrder]
,[ItemName]
,[ItemDescription]
,[ItemURL]
,[ItemImage]
,[CreateDate]
,[CreateUser]
,[LastUpdateDate]
,[LastUpdateUser]
,[module]
,[isactive])
SELECT
( 1
, (SELECT MAX(DisplayOrder) + 10 FROM tMrMenu)
, 'EDM Summary Text'
, 'EDM Summary Text'
, '/Offline/Reports/EdmSummaryText'
, 'cli.gif'
, GETDATE()
, 'Garry.Bargsley'
, GETDATE()
, 'Garry.Bargsley'
, 'MR'
, 1)
You have extra parenthesis:
INSERT INTO tMrMenu
([ParentId]
,[DisplayOrder]
,[ItemName]
,[ItemDescription]
,[ItemURL]
,[ItemImage]
,[CreateDate]
,[CreateUser]
,[LastUpdateDate]
,[LastUpdateUser]
,[module]
,[isactive])
SELECT
1
, (SELECT MAX(DisplayOrder) + 10 FROM tMrMenu)
, 'EDM Summary Text'
, 'EDM Summary Text'
, '/Offline/Reports/EdmSummaryText'
, 'cli.gif'
, GETDATE()
, 'Garry.Bargsley'
, GETDATE()
, 'Garry.Bargsley'
, 'MR'
, 1
Declare #max int
SET #max = (SELECT MAX...)
INSERT INTO tMrMenu...
SELECT
...
#max,
...
INSERT INTO tMrMenu
([ParentId]
,[DisplayOrder]
,[ItemName]
,[ItemDescription]
,[ItemURL]
,[ItemImage]
,[CreateDate]
,[CreateUser]
,[LastUpdateDate]
,[LastUpdateUser]
,[module]
,[isactive])
SELECT MAX(DisplayOrder) + 10
, 'EDM Summary Text'
, 'EDM Summary Text'
, '/Offline/Reports/EdmSummaryText'
, 'cli.gif'
, GETDATE()
, 'Garry.Bargsley'
, GETDATE()
, 'Garry.Bargsley'
, 'MR'
, 1
FROM tMrMenu