ODI KM substitution phase code it's getting wrong after submit - oracle-data-integrator

I'm writing KM's in ODI 12.2.1. I'm having the next problem:
after I'm finish writing a code in a task and press "OK" some lines of the code are changed (wrong):
example of correct code:
INSERT INTO TABLE <?=tempTblNmDt?>
SELECT
<%=odiRef.getAllTargetColList("", "cast([COL_NAME] as [DEST_CRE_DT]) as [COL_NAME]", ",\n\t", "","") %>
FROM
(
SELECT
<%=odiRef.getColList("", "<? if ( (\u0022[DEST_CRE_DT]\u0022==\u0022TIMESTAMP\u0022) && (\u0022[DATA_FORMAT]\u0022!=\u0022N/A\u0022) ) {?> from_unixtime(unix_timestamp( [EXPRESSION], 'yyyy-MM-dd HH:mm:ss')) AS [COL_NAME] <? } else { ?> cast([EXPRESSION] as [DEST_CRE_DT]) as [COL_NAME] <? }?>", ",\n\t", "","(INS and UPD)") %>
--TECHNICAL COLUMNS
,<?=vT_DL_CTI?> as T_DL_CTI
,from_unixtime(unix_timestamp()) as T_DL_INS_DT
,'<?=partDate?>' T_DL_COB_DT
FROM <?=tempTblNmStr?> <$=tableAlias$>
) SUBSELECT
After pressing Apply>OK:
INSERT INTO TABLE <?=tempTblNmDt?>
SELECT
<%=odiRef.getAllTargetColList("", "cast([COL_NAME] as [DEST_CRE_DT]) as [COL_NAME]", ",\n\t", "","") %>
FROM
(
SELECT
<%=odiRef.getColList("", "<? if ( (\u0022[DEST_CRE_DT]\u0022==\u0022TIMESTAMP\u0022) && (\u0022[DATA_FORMAT]\u0022!=\u0022N/A\u0022) ) {?> from_unixtime(unix_timestamp( [EXPRESSION], 'yyyy-MM-dd HH:mm:ss')) AS [COL_NAME] <? } else { ?> cast([EXPRESSION] as [DEST_CRE_DT]) as [COL_NAME] <? }?>", ",\n\t", "","(INS and UPD)") %>
--TECHNICAL COLUMNS
,<?=vT_DL_CTI?> as T_DL_CTI
,from_unixtime(unix_timestamp()) as T_DL_INS_DT
,'<?=partDate?>' T_DL_COB_DT
FROM <?=tempTblNmStr?> <$=tableAlias$>T
) SUBSELECT
Example 2:
Before:
<$ if (KM_ALL_DELIVERY_TYPE.equals("INTRA_DAY_DELTA"))
{
$>
<#
intraDayPartitionLocation = "#location";
#>
<$
}
$>
After:
<$ if (KM_ALL_DELIVERY_TYPE.equals("INTRA_DAY_DELTA"))
{
$>
<#
intraDayPartitionLocation = "#location";
#>
<
}
$>
Example 3
Before:
<$ if (KM_ALL_DELIVERY_TYPE.equals("INTRA_DAY_DELTA"))
{
$>
SELECT
ifnull(substring(location,instr(location,'datalake')),'N/A') location
FROM
hive.DBS
LEFT JOIN hive.TBLS
ON
(
DBS.DB_ID = TBLS.DB_ID
AND upper(TBLS.tbl_name) = '<$=tableShortNm$>_RAW'
)
LEFT JOIN hive.PARTITIONS
ON
(
TBLS.TBL_ID = PARTITIONS.TBL_ID
AND PARTITIONS.PART_NAME LIKE '%<$=partDate$>%'
)
LEFT JOIN hive.SDS
ON
(
PARTITIONS.SD_ID = SDS.SD_ID
)
WHERE
upper(DBS.name)='<$=rawSchema$>'
<$
}
$>
After:
<$ if (KM_ALL_DELIVERY_TYPE.equals("INTRA_DAY_DELTA"))
{
$>
SELECT
ifnull(substring(location,instr(location,'datalake')),'N/A') location
FROM
hive.DBS
LEFT JOIN hive.TBLS
ON
(
DBS.DB_ID = TBLS.DB_ID
AND upper(TBLS.tbl_name) = '<$=tableShortNm$>_RAW'
)
LEFT JOIN hive.PARTITIONS
ON
(
TBLS.TBL_ID = PARTITIONS.TBL_ID
AND PARTITIONS.PART_NAME LIKE '%<$=partDate$>%'
)
LEFT JOIN hive.SDS
ON
(
PARTITIONS.SD_ID = SDS.SD_ID
)
WHERE
upper(DBS.name>='<$=rawSchema$>'
<$
}
$>
This "broke code" is not always the same. Sometimes the substitution variables are broken. If need, I can provide more examples.
The workaround solution is to write your code in an external application (like notepad) and then to copy-paste the code in the section Command from the properties task (not in the task directly).
Does anyone know what is the cause of the problem?
It not happens on every task.

Related

EF Core 3.1 OrderByDescending curious T-SQL translation

I have the following Linq queries that differs only on the where clause:
Query 1:
var initialList = await
context.AlertDetailsDbSet
// Pouring the TrackedVehicule related graph
.Include(ad => ad.TrackedVehicule.Registration)
.Include(ad => ad.TrackedVehicule.Device)
.Include(ad => ad.TrackedVehicule.GpsBox.Icon)
.Include(ad => ad.TrackedVehicule.GpsBoxTypeNavigation.Icon)
.Include(ad => ad.TrackedVehicule.VehiculeGpsBoxInfo.VehiculeConfigurationNavigation)
// Loading the associated alert
.Include(ad => ad.Alert)
#if NETSTANDARD2_1
// This filter is not supported with EF Core 2.X
// It should be done client side
.Where(ad => ad.Alert.CompanyId == companyId && ad.Alert.AlertRule.Contains("SerializableContextAlert") && ad.AlertDateTime >= startDate && ad.AlertDateTime <= endDate && ad.TrackedVehicule != null && ad.TrackedVehicule.CompanyId == companyId && ad.TrackedVehicule.RowEnabled == true && (ad.TrackedVehicule.GpsBoxType == 29 || ad.TrackedVehicule.GpsBoxType == 12))
#endif
.Skip(0)
// A limit is applied on returned elements
.Take(1000)
.OrderByDescending(ad => ad.AlertDateTime)
// .Skip(skip)
// .Take(take)
// We disable the tracking mechanism because the context will be thrown away as soon as we have the data
.AsNoTracking()
// We want an asynchrounous execution
.ToListAsync(cancellationToken)
Query 2:
var initialList = await
context.AlertDetailsDbSet
// Pouring the TrackedVehicule related graph
.Include(ad => ad.TrackedVehicule.Registration)
.Include(ad => ad.TrackedVehicule.Device)
.Include(ad => ad.TrackedVehicule.GpsBox.Icon)
.Include(ad => ad.TrackedVehicule.GpsBoxTypeNavigation.Icon)
.Include(ad => ad.TrackedVehicule.VehiculeGpsBoxInfo.VehiculeConfigurationNavigation)
// Loading the associated alert
.Include(ad => ad.Alert)
#if NETSTANDARD2_1
// This filter is not supported with EF Core 2.X
// It should be done client side
.Where(ad => ad.Alert.CompanyId == companyId && ad.Alert.AlertRule.Contains("SerializableContextAlert") && ad.TrackedVehicule != null && ad.TrackedVehicule.RowEnabled == true && ad.TrackedVehicule.CompanyId == companyId && (ad.TrackedVehicule.GpsBoxType == 29 || ad.TrackedVehicule.GpsBoxType == 12) && ad.AckTime.HasValue == acknwoledged)
#endif
.OrderByDescending(ad => ad.AlertDateTime)
.Skip(skip)
.Take(take)
// We disable the tracking mechanism because the context will be thrown away as soon as we have the data
.AsNoTracking()
// We want an asynchrounous execution
.ToListAsync(cancellationToken)
Basically, the first query is (among aother things) filtering on a boolean property, while the second one is filtering on a range of dates.
My problem is that those queries are not translated to the same T-TSQL leading to different results.
TSQL 1 :
exec sp_executesql N'SELECT [t].[AlertDetailID], [t].[AckMachineName], [t].[AckPhoneNumber], [t].[AckTime], [t].[AckUserName], [t].[AlertDateTime], [t].[AlertID], [t].[AlertedCorridorId], [t].[AlertedItemId],
[t].[AssociatedVehiculeID], [t].[AssociatedVehiculeUserID], [t].[Context], [t].[CustomID], [t].[CustomInfo], [t].[DbInsertTime], [t].[IsFleetAlert], [t].[MessageStatus], [t].[ReceivedTime], [t].[RowVersion],
[t].[SafeProtectCustomInfo], [t].[TrackedVehiculeID], [t].[TrackedVehiculeUserID], [v0].[VehiculeID], [v0].[Address], [v0].[AddressProtocol], [v0].[BoardID], [v0].[Category], [v0].[CompanyID], [v0].[CustomId], [v0].[DbInsertTime], [v0].[Description], [v0].[GpsBoxSubType], [v0].[GpsBoxTrackingDelay], [v0].[GpsBoxType], [v0].[HardwareID], [v0].[HasGeoWorker], [v0].[IconID], [v0].[Name], [v0].[PhoneNumber], [v0].[RowEnabled], [v0].[RowVersion], [v0].[VehiculeUserID], [r].[VehiculeID], [r].[CompanyId], [r].[LatestRegistrationStatusChangeDate], [r].[RegistrationMailSent], [r].[RegistrationStatusId], [d].[VehiculeID], [d].[AppVersion], [d].[Brand], [d].[Details], [d].[Imei], [d].[Model], [d].[Name], [d].[OsVersion], [d].[RowVersion], [g].[GpsBoxTypeID], [g].[GpsBoxSubTypeID], [g].[IconId], [g].[Name], [i].[IconId], [i].[Category], [i].[FileName], [i].[Icon], [g0].[GpsBoxTypeId], [g0].[Category], [g0].[IconId], [g0].[Name], [i0].[IconId], [i0].[Category], [i0].[FileName], [i0].[Icon], [v1].[VehiculeID], [v1].[BoardConfiguration], [v1].[BoardConnected], [v1].[BoardCurrentAddress], [v1].[BoardLastCommunicationTime], [v1].[Connected], [v1].[CurrentAddress], [v1].[CurrentDelay], [v1].[FuelConsumptionEstimationTime], [v1].[HeartBeatPeriod], [v1].[InsureCoherence], [v1].[KillHedgehog], [v1].[LastCommunicationTime], [v1].[LastConnexionTime], [v1].[LastParkMileage], [v1].[LastParkMileageTime], [v1].[NormalTrackingMode], [v1].[SmartModeDelay], [v1].[SmartModeDistance], [v1].[TimeModeDelay], [v1].[UpdateStartTime], [v1].[UpdateStatus], [v1].[VehiculeConfiguration], [g1].[ConfigurationID], [g1].[ConfigName], [g1].[Firmware], [g1].[GpsBoxType], [g1].[Master], [g1].[MasterName], [g1].[SimContract], [g1].[System], [a1].[AlertID], [a1].[AlertEnabled], [a1].[AlertRule], [a1].[Always], [a1].[CalendarID], [a1].[Category], [a1].[CompanyID], [a1].[Description], [a1].[DisplayName], [a1].[RowEnabled], [a1].[RowVersion], [a1].[Shared], [a1].[UserID]
FROM (
SELECT [a].[AlertDetailID], [a].[AckMachineName], [a].[AckPhoneNumber], [a].[AckTime], [a].[AckUserName], [a].[AlertDateTime], [a].[AlertID], [a].[AlertedCorridorId], [a].[AlertedItemId], [a].[AssociatedVehiculeID], [a].[AssociatedVehiculeUserID], [a].[Context], [a].[CustomID], [a].[CustomInfo], [a].[DbInsertTime], [a].[IsFleetAlert], [a].[MessageStatus], [a].[ReceivedTime], [a].[RowVersion], [a].[SafeProtectCustomInfo], [a].[TrackedVehiculeID], [a].[TrackedVehiculeUserID], [a0].[AlertID] AS [AlertID0]
FROM [AlertDetail] AS [a]
INNER JOIN [Alert] AS [a0] ON [a].[AlertID] = [a0].[AlertID]
LEFT JOIN [Vehicule] AS [v] ON [a].[TrackedVehiculeID] = [v].[VehiculeID]
WHERE (((((([a0].[CompanyID] = #__companyId_0) AND (CHARINDEX(N''SerializableContextAlert'', [a0].[AlertRule]) > 0)) AND [v].[VehiculeID] IS NOT NULL) AND ([v].[RowEnabled] = CAST(1 AS bit))) AND ([v].[CompanyID] = #__companyId_0)) AND (([v].[GpsBoxType] = 29) OR ([v].[GpsBoxType] = 12))) AND (CASE
WHEN [a].[AckTime] IS NOT NULL THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END = #__acknwoledged_1)
ORDER BY [a].[AlertDateTime] DESC
OFFSET #__p_2 ROWS FETCH NEXT #__p_3 ROWS ONLY
) AS [t]
LEFT JOIN [Vehicule] AS [v0] ON [t].[TrackedVehiculeID] = [v0].[VehiculeID]
LEFT JOIN [SafeProtect].[Registration] AS [r] ON [v0].[VehiculeID] = [r].[VehiculeID]
LEFT JOIN [SafeProtect].[Device] AS [d] ON [v0].[VehiculeID] = [d].[VehiculeID]
LEFT JOIN [GpsBoxSubType] AS [g] ON ([v0].[GpsBoxType] = [g].[GpsBoxTypeID]) AND ([v0].[GpsBoxSubType] = [g].[GpsBoxSubTypeID])
LEFT JOIN [cst].[Icon] AS [i] ON [g].[IconId] = [i].[IconId]
LEFT JOIN [GpsBoxType] AS [g0] ON [v0].[GpsBoxType] = [g0].[GpsBoxTypeId]
LEFT JOIN [cst].[Icon] AS [i0] ON [g0].[IconId] = [i0].[IconId]
LEFT JOIN [VehiculeGpsBoxInfo] AS [v1] ON [v0].[VehiculeID] = [v1].[VehiculeID]
LEFT JOIN [GpsBoxConfiguration] AS [g1] ON [v1].[VehiculeConfiguration] = [g1].[ConfigurationID]
INNER JOIN [Alert] AS [a1] ON [t].[AlertID] = [a1].[AlertID]
ORDER BY [t].[AlertDateTime] DESC',N'#__companyId_0 int,#__acknwoledged_1 bit,#__p_2 int,#__p_3 int',#__companyId_0=1013,#__acknwoledged_1=0,#__p_2=0,#__p_3=999
TSQL 2:
exec sp_executesql N'SELECT [t].[AlertDetailID], [t].[AckMachineName], [t].[AckPhoneNumber], [t].[AckTime], [t].[AckUserName], [t].[AlertDateTime], [t].[AlertID], [t].[AlertedCorridorId], [t].[AlertedItemId],
[t].[AssociatedVehiculeID], [t].[AssociatedVehiculeUserID], [t].[Context], [t].[CustomID], [t].[CustomInfo], [t].[DbInsertTime], [t].[IsFleetAlert], [t].[MessageStatus], [t].[ReceivedTime], [t].[RowVersion],
[t].[SafeProtectCustomInfo], [t].[TrackedVehiculeID], [t].[TrackedVehiculeUserID], [v0].[VehiculeID], [v0].[Address], [v0].[AddressProtocol], [v0].[BoardID], [v0].[Category], [v0].[CompanyID], [v0].[CustomId], [v0].[DbInsertTime], [v0].[Description], [v0].[GpsBoxSubType], [v0].[GpsBoxTrackingDelay], [v0].[GpsBoxType], [v0].[HardwareID], [v0].[HasGeoWorker], [v0].[IconID], [v0].[Name], [v0].[PhoneNumber], [v0].[RowEnabled], [v0].[RowVersion], [v0].[VehiculeUserID], [r].[VehiculeID], [r].[CompanyId], [r].[LatestRegistrationStatusChangeDate], [r].[RegistrationMailSent], [r].[RegistrationStatusId], [d].[VehiculeID], [d].[AppVersion], [d].[Brand], [d].[Details], [d].[Imei], [d].[Model], [d].[Name], [d].[OsVersion], [d].[RowVersion], [g].[GpsBoxTypeID], [g].[GpsBoxSubTypeID], [g].[IconId], [g].[Name], [i].[IconId], [i].[Category], [i].[FileName], [i].[Icon], [g0].[GpsBoxTypeId], [g0].[Category], [g0].[IconId], [g0].[Name], [i0].[IconId], [i0].[Category], [i0].[FileName], [i0].[Icon], [v1].[VehiculeID], [v1].[BoardConfiguration], [v1].[BoardConnected], [v1].[BoardCurrentAddress], [v1].[BoardLastCommunicationTime], [v1].[Connected], [v1].[CurrentAddress], [v1].[CurrentDelay], [v1].[FuelConsumptionEstimationTime], [v1].[HeartBeatPeriod], [v1].[InsureCoherence], [v1].[KillHedgehog], [v1].[LastCommunicationTime], [v1].[LastConnexionTime], [v1].[LastParkMileage], [v1].[LastParkMileageTime], [v1].[NormalTrackingMode], [v1].[SmartModeDelay], [v1].[SmartModeDistance], [v1].[TimeModeDelay], [v1].[UpdateStartTime], [v1].[UpdateStatus], [v1].[VehiculeConfiguration], [g1].[ConfigurationID], [g1].[ConfigName], [g1].[Firmware], [g1].[GpsBoxType], [g1].[Master], [g1].[MasterName], [g1].[SimContract], [g1].[System], [a1].[AlertID], [a1].[AlertEnabled], [a1].[AlertRule], [a1].[Always], [a1].[CalendarID], [a1].[Category], [a1].[CompanyID], [a1].[Description], [a1].[DisplayName], [a1].[RowEnabled], [a1].[RowVersion], [a1].[Shared], [a1].[UserID]
FROM (
SELECT [a].[AlertDetailID], [a].[AckMachineName], [a].[AckPhoneNumber], [a].[AckTime], [a].[AckUserName], [a].[AlertDateTime], [a].[AlertID], [a].[AlertedCorridorId], [a].[AlertedItemId], [a].[AssociatedVehiculeID], [a].[AssociatedVehiculeUserID], [a].[Context], [a].[CustomID], [a].[CustomInfo], [a].[DbInsertTime], [a].[IsFleetAlert], [a].[MessageStatus], [a].[ReceivedTime], [a].[RowVersion], [a].[SafeProtectCustomInfo], [a].[TrackedVehiculeID], [a].[TrackedVehiculeUserID], [a0].[AlertID] AS [AlertID0]
FROM [AlertDetail] AS [a]
INNER JOIN [Alert] AS [a0] ON [a].[AlertID] = [a0].[AlertID]
LEFT JOIN [Vehicule] AS [v] ON [a].[TrackedVehiculeID] = [v].[VehiculeID]
WHERE ((((((([a0].[CompanyID] = #__companyId_0) AND (CHARINDEX(N''SerializableContextAlert'', [a0].[AlertRule]) > 0)) AND ([a].[AlertDateTime] >= #__startDate_1)) AND ([a].[AlertDateTime] <= #__endDate_2)) AND [v].[VehiculeID] IS NOT NULL) AND ([v].[CompanyID] = #__companyId_0)) AND ([v].[RowEnabled] = CAST(1 AS bit))) AND (([v].[GpsBoxType] = 29) OR ([v].[GpsBoxType] = 12))
ORDER BY (SELECT 1)
OFFSET #__p_3 ROWS FETCH NEXT #__p_4 ROWS ONLY
) AS [t]
LEFT JOIN [Vehicule] AS [v0] ON [t].[TrackedVehiculeID] = [v0].[VehiculeID]
LEFT JOIN [SafeProtect].[Registration] AS [r] ON [v0].[VehiculeID] = [r].[VehiculeID]
LEFT JOIN [SafeProtect].[Device] AS [d] ON [v0].[VehiculeID] = [d].[VehiculeID]
LEFT JOIN [GpsBoxSubType] AS [g] ON ([v0].[GpsBoxType] = [g].[GpsBoxTypeID]) AND ([v0].[GpsBoxSubType] = [g].[GpsBoxSubTypeID])
LEFT JOIN [cst].[Icon] AS [i] ON [g].[IconId] = [i].[IconId]
LEFT JOIN [GpsBoxType] AS [g0] ON [v0].[GpsBoxType] = [g0].[GpsBoxTypeId]
LEFT JOIN [cst].[Icon] AS [i0] ON [g0].[IconId] = [i0].[IconId]
LEFT JOIN [VehiculeGpsBoxInfo] AS [v1] ON [v0].[VehiculeID] = [v1].[VehiculeID]
LEFT JOIN [GpsBoxConfiguration] AS [g1] ON [v1].[VehiculeConfiguration] = [g1].[ConfigurationID]
INNER JOIN [Alert] AS [a1] ON [t].[AlertID] = [a1].[AlertID]
ORDER BY [t].[AlertDateTime] DESC',N'#__companyId_0 int,#__startDate_1 datetime,#__endDate_2 datetime,#__p_3 int,#__p_4 int',#__companyId_0=1013,#__startDate_1='2020-09-07 21:59:59',#__endDate_2='2020-09-08 21:59:59',#__p_3=0,#__p_4=999
It took me some time to spot a tiny by impacting difference between the two queries.
If you look carefully, the first subquery contains an ORDER BY which is what I want:
ORDER BY [a].[AlertDateTime] DESC
The second linq query, despite using the same OderBy is translated to a TSQL subquery that contains
ORDER BY (SELECT 1)
That sounds crasy to me.
I hope that someone could explain what is going on.
It has nothing to do with filtering (Where), but the order of ordering (OrderBy{Descending}) and row limiting (Skip / Take) operators in LINQ query.
The fake ORDER BY (SELECT 1) definitely is generated for the LINQ query having the following fragment
.Skip(0)
.Take(1000)
.OrderByDescending(ad => ad.AlertDateTime)
// .Skip(skip)
// .Take(take)
As you can see, here the row limiting operators are applied before the ordering. Since SqlServer OFFSET FETCH SQL construct requires ORDER BY, EF Core translator inserts fake one (it would have been better to throw exception or let the database do that, but that's another story. Actually before EF Core 3.0 there was CoreEventId.RowLimitingOperationWithoutOrderByWarning which could be configured to throw, but for some unknown reason it has been obsoleted and has no effect in EF Core 3.x).
The correct place of row limiting of course is after ordering, as it is in the commented out code. So simply remove the (temporary I guess) Skip(0).Take(1000) and uncomment the .Skip(skip).Take(take). Problem solved.

Change specific values in GSMA TAP3 file

I'm trying to change charge values from MO (originating) calls in GSM TAP3.11 files, but it doesn't handle the needed
here i can access directly duration value but with charge value its different case as attached, im tring to change the charge value on (1) chargeDetail and (2) chargeDetail (first and second records in the ChargeDetailList in the screenshot below).
My background is only with python, this's the first time with perl. I use it because after searching I believe that only perl can handle TAP files. (see TAP3::Tap3edit)
$struct=$tap3->structure;
my $key;
# Will scan all the calls for MOC's.
foreach $key ( #{$struct->{'transferBatch'}->{'callEventDetails'} } ) {
foreach ( keys %{$key} ) {
if ( $_ eq "mobileOriginatedCall" )
{
$duration= $key->{$_}->{'basicCallInformation'}->{'totalCallEventDuration'};
delete $key->{$_}{'basicCallInformation'}{'basicServiceUsedList'}[0]{'chargeInformationList'}[0]{'chargeDetailList'}[0]{'charge'};
$key->{$_}{'basicCallInformation'}{'basicServiceUsedList'}[0]{'chargeInformationList'}[0]{'chargeDetailList'}[0]{'charge'}=$duration * 0.12 /0.6;
$new_charge_value = $key->{$_}{'basicCallInformation'}{'basicServiceUsedList'}[0]{'chargeInformationList'}[0]{'chargeDetailList'}[0]{'charge'}=$duration * 0.12 /0.6;
}
}
}
$tap3->encode("$tap_file") or die $tap3->error;
The exists() function in Perl is used to check whether an element in an given array or hash exists or not. This function returns 1 if the desired element is present in the given array or hash else returns 0.
$Tax_Rate = 3;
$Exchange_Rate = 3;
$Rate_Plan_Charge_Rate = 8;
my $key;
# Will scan all the calls for MOC's.
foreach $key ( #{$struct->{'transferBatch'}->{'callEventDetails'} } ) {
foreach ( keys %{$key} ) {
if ( $_ eq "mobileOriginatedCall" )
{
if (exists $key->{$_}->{'basicCallInformation'}->{'totalCallEventDuration'}){
$duration = $key->{$_}->{'basicCallInformation'}->{'totalCallEventDuration'};
if (exists $key->{$_}->{basicServiceUsedList}[0]{chargeInformationList}[0]{chargeDetailList}[0]){
$key->{$_}->{basicServiceUsedList}[0]{chargeInformationList}[0]{chargeDetailList}[0]{charge}=($duration * $Rate_Plan_Charge_Rate) / $Exchange_Rate;
}
if (exists $key->{$_}->{basicServiceUsedList}[0]{chargeInformationList}[0]{chargeDetailList}[1]){
$key->{$_}->{basicServiceUsedList}[0]{chargeInformationList}[0]{chargeDetailList}[1]{charge}=($duration * $Rate_Plan_Charge_Rate) / $Exchange_Rate;
}
$New_Charge = $key->{$_}->{basicServiceUsedList}[0]{chargeInformationList}[0]{chargeDetailList}[0]{charge};
if (exists $key->{$_}->{basicServiceUsedList}[0]{chargeInformationList}[0]{taxInformation}[0]){
$key->{$_}->{basicServiceUsedList}[0]{chargeInformationList}[0]{taxInformation}[0]{taxValue}=($New_Charge / $Tax_Rate);
}
if (exists $key->{$_}->{basicServiceUsedList}[0]{chargeInformationList}[0]{taxInformation}[1]){
$key->{$_}->{basicServiceUsedList}[0]{chargeInformationList}[0]{taxInformation}[0]{taxValue}=($New_Charge / $Tax_Rate);
}
}
}
}
}

Execute Microsoft SQL query on R Shiny

I am writing an R-Shiny app. Can some one tell me how to execute a Microsoft SQL query in R Shiny ?
This is what I have done so far:
data <- reactive({
conn <- reactive ({ databaseOpen(serverName="[serverName]", databaseName=[dbName])})
qr <- reactive ({ SELECT * from myTable })
res <- reactive ({databaseQuery(conn = conn,query = qr)})
close(conn)
View(res)
})
Any help is appreciated !
I was able to call a query by creating a function outside of the server and ui functions (in other words, in a global.r). Then the server function could call that query function using one of the inputs in the function.
Here is my code:
queryfunction <- function(zipper){
odbcChannel <- odbcConnect("myconnection")
querydoc <- paste0("
SELECT distinct *
FROM mydb
where substring(nppes_provider_zip,1,2) = '43'
and [provider_type] = 'General Practice'
")
pricetable <- sqlQuery(odbcChannel, querydoc)
close(odbcChannel)
pricetable[which(substring(pricetable$nppes_provider_zip,1,5)==zipper),]
}
server <- shinyServer(function(input, output) {
output$mytable1 <- renderDataTable(data.table(queryfunction(input$zip)))
})
I figured it out. It can be done as:
server.r
serverfun<-function(input, output){
# Storing values in myData variable
myData <- reactive({
# Opening database connection
conn <- databaseOpen(serverName = "myServer",databaseName = "myDB")
# Sample query which uses some input
qr <- paste( "SELECT name FROM Genes g WHERE Id = ",input$myId," ORDER BY name")
# Storing results
res <- databaseQuery(conn = conn,query = qr)
# closing database
databaseClose(conn)
# Returning results
res
})
output$tbTable <- renderTable({
# Checking if myData is not null
if(is.null(myData())){return ()}
# return myData
myData()
})
ui.r
library("shiny")
shinyUI(
pageWithSidebar(
headerPanel("Hide Side Bar example"),
sidebarPanel(
textInput("Id", "Enter ID below","1234")
),
mainPanel(
tabsetPanel(
tabPanel("Data", tableOutput("tbTable"))
)
)
)
)

Use of uninitialized value $end_time1 in string eq .......error in perl

i want to retrive some data from my database,if $end_time1 is null then will be update table ,otherwise will do nothing ,but when i run the code,i found the $end_time1 is null,then will be update the table ,but if not null ,it's will be return the error :
Use of uninitialized value $end_time1 in string eq ........
part of my code :
my $select_sth = $dbh->prepare("SELECT id ,H1, H2, addr1, addr2, time_1, time_2,
end_time_1,end_time_2,count1,count2 FROM service") or die "$dbh->errstr";
$select_sth->execute() or die "$dbh->errstr";
while (my #row_ref = $select_sth->fetchrow_array)
{
my $Rid = $row_ref[0];
my $addr1 = $row_ref[3];
my $addr2 = $row_ref[4];
my $end_time1 = "NULL" unless $row_ref[7];
my $end_time2 = "NULL" unless $row_ref[8];
my $count1 = $row_ref[9];
my $count2 = $row_ref[10];
if($end_time1 eq "NULL")
{
print "$end_time1 is null\n";
$dbh->do ("update service set end_time_1 = '$datetime_now' where id = $Rid");
}
}
please someone what's wrong with my code ?how to fix ?
Your current code only sets $endtime1 if $row_ref[7] is not defined. This means that $endtime1 is undefined if $row_ref[7] does have a value, so you get that Use of uninitialized value $end_time1 in string eq... error when you test it.
Change your code so that $endtime1 will either be set to $row_ref[7] (if it is defined) or to NULL:
my $end_time1 = $row_ref[7] || 'NULL';
Then you can use your existing code:
if ($end_time1 eq "NULL")
{
print "end_time1 is null\n";
$dbh->do ("update service set end_time_1 = '$datetime_now' where id = $Rid");
}
The same issue exists for $endtime2, so you may want to make a similar alteration.
Use defined:
if ( !defined $end_time1 ) {
print "end_time1 is null\n";
}

Array of sorted key/value pairs to sorted array of keys and hash

I am developing a Catalyst app which uses Template::Toolkit as template engine. One page needs a list of equal input elements. They can be taken from an array but I need both sort order and a descriptive label for the element.
For having a sort order I would use an array. For storing an additional value per key a hash is perfect. How to combine both in TT? I could use both things but that seems ugly and can cause mistakes when changing the fields.
However, I prefer doing this in TT because both the descriptions and the order of form elements is a front-end thing.
This is how I would do it in pure Perl:
#!/usr/bin/perl -w
use 5.10.0;
# definition of description and order in 1 step
my #fields = (
property_foo => "Some property",
property_bar => "Important field",
property_baz => "Something else",
);
# extract information
my %descriptions = #fields;
my #order = #fields[grep {($_ + 1) % 2} 0..(scalar #fields - 1)];
say "=== natural perl sort order ===";
foreach (keys %descriptions) {say $_};
say "=== wanted output ===";
foreach (#order) {
say $descriptions{$_} . ": [label for $_]";
}
Outputs:
=== natural perl sort order ===
property_baz
property_foo
property_bar
=== wanted output ===
Some property: [label for property_foo]
Important field: [label for property_bar]
Something else: [label for property_baz]
This is what I write in my template:
[%
order = (
property_foo,
property_bar,
property_baz,
);
descriptions = {
property_foo => "Some property",
property_bar => "Important field",
property_baz => "Something else",
}
FOREACH property IN order %]
[% descriptions.$property %]: <input name="[% property %]" />
[% END %]
However, it is really ugly to have the same information (list of fields) twice. I want to avoid editing the list twice and with a longer list of fields it gets really annoying (about 20 items, not long enough to do some database stuff).
It's amazing how people complicate easy stuff!
You don't need the #fields array. Please read the perldoc about keys, values and sort.
# untested sketch
my %description = ( prop23 => "foo", prop24 => "bar" );
foreach my $key(sort (keys %description)) {
print $key, " is: ", $description{$key}, "\n"; # or whatever
}
Addendum: Regarding the order of keys, just do the following:
my #arbitraryOrder = qw(prop42 prop35 prop1 ...); # allows to map number to key
my %keytoNumber = (); # will map keys to numbers
foreach my $i(0..$#arbitraryOrder) $keyToNumber{$arbitraryOrder[$i]} = $i;
Writing the comparison function for sort is left as an exercise :)
You might be interested in Tie::IxHash
It is a "hash" that keeps the order in which you add keys (value updates do not affect sorting).
EDIT: A brief example:
use warnings;
use strict;
use Tie::IxHash;
tie my %H, "Tie::IxHash";
$H{foo} = 1;
$H{bar} = 2;
# order of keys is now always 'foo', 'bar'
print keys %H;
EDIT2: I've tried it out, and it actually works:
#!/usr/bin/perl -w
use strict;
use Template;
use Tie::IxHash;
# my %h; # this breaks ordering
tie my %H, "Tie::IxHash"; # this keeps ordering
#H{qw/f oo b a r/} = 1..100;
# don't define $H{'keys'} or you'll get disappointed
my $tpl = Template->new();
$tpl->process(\*DATA, {hash=>\%H});
__DATA__
[% FOREACH k IN hash.keys %]
[% k %] => [% hash.$k %]
[% END %]
If you need ordering and multiple pieces of information then you should consider an array of hash references.
my #fields = (
{ id => 'property_foo',
label => 'Some property' },
{ id => 'property_bar',
label => 'Important field' },
{ id => 'property_baz',
label => 'Something else' },
);
foreach (#fields) {
print "ID: $_->{id}, Label: $_->{label}\n";
}
If the complexity increases much beyond this, you might consider replacing the hashrefs with real objects.
And, in TT, it looks like this:
[%-
properties = [
{id => 'property_foo',
label => 'Some property'},
{id => 'property_bar',
label => 'Important field'},
{id => 'property_baz',
label => 'Something else'},
];
-%]
[%- FOREACH property IN properties %]
[% property.label %]: <input name="[% property.id %]" />
[% END %]
Actually if you want your hash alphabetically sorted by key, Template::Toolkit does that for you.
test.pl
use strict;
use warnings;
use Template;
my %hash = qw' a 1 b 2 c 3 ';
my $config = {
INCLUDE_PATH => '/search/path',
};
my $input = 'test.tt2';
my $template = Template->new( $config );
$template->process( $input, {
hash => \%hash,
})
test.tt2
[% FOREACH hash -%]
[% key %] => [% value %]
[% END %]
output
a => 1
b => 2
c => 3

Resources