Passing a variable into SQL string - sql

I'm modifying someone else's showershell script that's used within our database to try and have it do some extra steps behind the scenes: reject code, location code, and start date.
It starts by asking for 3 values to pass as variables, but I want to add 2 additional values using a dictionary based on the location code. I don't want to share the entire batch - I know it works without this one specific part, but I'll include enough to illustrate my point.
The issue is with the variables $AREA1 and $AREA2 - these are what I'm trying to add.
The "parameters" are being injected using one way where it asks for the user to supply them but i don't want the user to supply these, they're supposed to be a lookup.
For instance, if the LOC was 5300 then AREA1 should be 101 and AREA 2 should be 111.
param(
[ImdsParameter(FullName = "REJ_CODE", Description = "Enter a 4 digit reject code to filter the data. Will not run without one.", Length = 4)]
[string] $REJ,
[ImdsParameter(FullName = "LOC", Description = "The Location code you want to run this against. Example 5300.", Length = 4)]
[string] $LOC,
[ImdsParameter(FullName = "STDTE", Description = "Start date. This is the start date from how back to run the report. Example 2021-01-01", Length = 10)]
[string] $STDTE
)
$areaStart = #{
5300 = 101 ;
5304 = 112 ;
5305 = 123 ;
5306 = 134 ;
//there’s well over 100 of these
}
$areaEnd = #{
5300 = 111 ;
5304 = 122 ;
5305 = 133 ;
5306 = 144 ;
//same
}
$AREA1 = $areaStart.Get_Item($LOC)
$AREA2 = $areaEnd.Get_Item($LOC)
$jobSql = #"
SELECT TB1.dataitem1,
TB1. Dataitem2,
TB1. Dataitem3,
TB2. Dataitem1
FROM firstTable AS TB1 INNER JOIN secondTable AS TB2
ON TB1. dataitem = TB2. dataitem
WHERE TB1.LOCATION = #LOC AND TB2.AREA BETWEEN '$($AREA1)' AND '$($AREA2)'
"#
$edbms = Get-Rdms -SQL $jobSql -Parameters #{LOC = $LOC; REJ = $REJ; STDTE = $STDTE; }
$edbms | ConvertTo-Csv -NoTypeInformation
EDIT: I need to add that the script will run, but returns no data. If I just plug the SQL in with all the values manually, it will run just fine.
Thank you for your time.

The values in the SQL were being treated as strings while the values in the dictionaries were being treated as numbers.
I changed this:
5300 = 101 ;
5304 = 112 ;
5305 = 123 ;
5306 = 134 ;
To this:
'5300' = '101' ;
'5304' = '112' ;
'5305' = '123' ;
'5306' = '134' ;
And it provided the data expected.

Related

Azure AlertRule queries sometimes changes query

I have an Azure AlertRule what validates a query, where to tables are joining on a timestamp.
Is seems like Azure is changing the query, replacing the statement bin(..) with bin_at(..).
The Original query:
The query, opened after the alert triggered.
In my case this change is enough to alter the result of the query, becuase the extra added parameter (yellow arrow).
Is there any way around the issue?
EDIT:
as David pointed out in the comments -
This behaviour can be reproduced by running this kql as the query of an alart rule:
print bin(now(), 1h)
Original:
For completness, i've added the entier query here. I was not able to shorten it more that this. (sorry)
let frame_size = 1h;
let messages = datatable (timestamp: datetime )
[
datetime(2022-11-09T23:01:00Z),datetime(2022-11-09T23:02:00Z),datetime(2022-11-09T23:03:00Z),datetime(2022-11-09T23:04:00Z),
datetime(2022-11-09T22:01:00Z),datetime(2022-11-09T22:02:00Z),datetime(2022-11-09T22:03:00Z),datetime(2022-11-09T22:04:00Z),
datetime(2022-11-09T21:01:00Z),datetime(2022-11-09T21:02:00Z),datetime(2022-11-09T21:03:00Z),datetime(2022-11-09T21:04:00Z),
datetime(2022-11-09T20:01:00Z),datetime(2022-11-09T20:02:00Z),datetime(2022-11-09T20:03:00Z),datetime(2022-11-09T20:04:00Z),
datetime(2022-11-09T19:01:00Z),datetime(2022-11-09T19:02:00Z),datetime(2022-11-09T19:03:00Z),datetime(2022-11-09T19:04:00Z),
datetime(2022-11-09T18:01:00Z),datetime(2022-11-09T18:02:00Z),datetime(2022-11-09T18:03:00Z),datetime(2022-11-09T18:04:00Z),
datetime(2022-11-09T17:01:00Z),datetime(2022-11-09T17:02:00Z),datetime(2022-11-09T17:03:00Z),datetime(2022-11-09T17:04:00Z),
datetime(2022-11-09T16:01:00Z),datetime(2022-11-09T16:02:00Z),datetime(2022-11-09T16:03:00Z),datetime(2022-11-09T16:04:00Z),
datetime(2022-11-09T15:01:00Z),datetime(2022-11-09T15:02:00Z),datetime(2022-11-09T15:03:00Z),datetime(2022-11-09T15:04:00Z),
datetime(2022-11-09T14:01:00Z),datetime(2022-11-09T14:02:00Z),
datetime(2022-11-09T13:01:00Z),datetime(2022-11-09T13:02:00Z),
datetime(2022-11-09T12:01:00Z),datetime(2022-11-09T12:02:00Z),
datetime(2022-11-09T11:01:00Z),datetime(2022-11-09T11:02:00Z),
datetime(2022-11-09T10:01:00Z),datetime(2022-11-09T10:02:00Z),
datetime(2022-11-09T09:01:00Z),datetime(2022-11-09T09:02:00Z),
datetime(2022-11-09T08:01:00Z),datetime(2022-11-09T08:02:00Z),
datetime(2022-11-09T07:01:00Z),datetime(2022-11-09T07:02:00Z),
datetime(2022-11-09T06:01:00Z),datetime(2022-11-09T06:02:00Z),
datetime(2022-11-09T06:01:00Z),datetime(2022-11-09T06:02:00Z),
datetime(2022-11-09T05:01:00Z),datetime(2022-11-09T05:02:00Z),
datetime(2022-11-09T04:01:00Z),datetime(2022-11-09T04:02:00Z),
datetime(2022-11-09T03:01:00Z),datetime(2022-11-09T03:02:00Z),
datetime(2022-11-09T02:01:00Z),datetime(2022-11-09T02:02:00Z),
datetime(2022-11-09T01:01:00Z),datetime(2022-11-09T01:02:00Z),
datetime(2022-11-09T00:01:00Z),datetime(2022-11-09T00:02:00Z),
];
let create_time_intervals = (start_datetime: datetime, end_datetime: datetime, frame_size: timespan)
{
let hourly_distribution_as_dk_time = datatable (hour: int, expected_documents_count: int)
[0,2, 1,2, 2,2, 3,2, 4,2, 5,2, 6,2, 7,2, 8,2, 9,2, 10,2, 11,2, 12,2, 13,2, 14,2, 15,4, 16,4, 17,4, 18,4, 19,4, 20,4, 21,4, 22,4, 23,4 ]
;
let start_datetime_dk = datetime_utc_to_local(start_datetime, "Europe/Copenhagen");
let end_datetime_dk = datetime_utc_to_local(end_datetime, "Europe/Copenhagen");
// Generate all time frames for given interval excluding the first incomplete frame.
range frame_start from bin(start_datetime + frame_size, frame_size) to end_datetime step frame_size
| project bin(frame_start, frame_size)
| extend date_dk = datetime_utc_to_local(frame_start, "Europe/Copenhagen")
| extend hour = toint(datetime_part("Hour", date_dk))
| join kind=leftouter hourly_distribution_as_dk_time on hour
| project frame_start, expected_documents_count
| order by frame_start asc
};
let msg = messages
| where timestamp >= ago(1h)
|summarize cnt = count()
by frame_start = bin(timestamp,frame_size); // *** <==== this bin(..) changes when running ***
let frame_results = create_time_intervals(ago(1h), now(), frame_size)
| join kind=leftouter msg on frame_start
| extend ok = cnt;
frame_results
| summarize
sum_expected = sum(expected_documents_count),
sum_ok = sum(ok)
| extend ok = sum_expected == sum_ok
| extend ok_int = toint(ok) //for alerting purposes
Well, an obvious work-around would be to replace bin with bin_at, e.g. -
let timestamp = datetime(2000-03-04 11:22:33);
let frame_size = 1h;
print bin_at(timestamp, frame_size, datetime(2000))
print_0
2000-03-04T11:00:00Z
Fiddle

QlikView Convert 1753-01-01 00:00:00.000 to NULL

I am trying to convert data from SQL as 1753-01-01 00:00:00.000 to be shown as NULL values in QlikView.
I do the following in the QlikView Load statements -
SET NullTimeStamp = if ($1 = '1753-01-01 00:00:00', null(), $1);
Then use it when LOAD:
LOAD
$(NullTimeStamp(YourDateField1)) AS YOURDATEFIELD1,
$(NullTimeStamp(YourDateField2)) AS YOURDATEFIELD2,
$(NullTimeStamp(YourDateField3)) AS YOURDATEFIELD3
However, I have many fields with Time and Dates in my tables so I was wondering if there is a more elegant way of solving this issue?
Ive done something similar in the past. The idea is to generate part of the load script in a variable and then use this variable as part of the next load script
DummyData:
Load * Inline [
Something1 , Something2, Something3, Something4, Something5
1753-01-01 00:00:00.000, 2, 3, 4, 1753-01-01 00:00:00.000
];
SET NullTimeStamp = if ($1 = '1753-01-01 00:00:00', null(), $1);
// Define a temp table
// that holds list of fields that have to be checked with NullTimeStamp
Fields:
Load * Inline [
FieldNames
Something1
Something2
Something3
Something4
Something5
];
let FieldsConcatenation = '';
// loop through the NullTimeStamp-ed fields
for a = 1 to NoOfRows('Fields')
let f = FieldValue('FieldNames', a);
// concatenate each iteration to form part of the RealLoad table script
let FieldsConcatenation = '$(FieldsConcatenation)' & '$(NullTimeStamp(' & '$(f)' & ')) as ' & Upper('$(f)') & ',' & chr(13);
next
// remove the last comma
let FieldsConcatenation = left('$(FieldsConcatenation)', Index('$(FieldsConcatenation)', ',' , -1) -1);
// we dont need this anymore
Drop Table Fields;
// add FieldsConcatenation variable as part of the load script
RealLoad:
Load
$(FieldsConcatenation),
'a' as LoadTheRestHere
Resident
DummyData;
// we dont need this anymore
Drop Table DummyData;
FieldsConcatenation variable will have the following content:
The original table:
And the final table:

How to get a variable name that is created in a for loop

Basically I have a for loop that is creating variables based on data in a database, I then have an event listener that is also created based on the for loop and I want to know which text is pressed
Ive tried events in the function, creating a variable for my row.name etc.
for row in db:nrows( "SELECT * FROM Students WHERE Class = '"..class.."'" ) do
print(row.Name)
--track how many students there are
count = count+1
--When displaying the names, put them in line, if they go below 1000 y level, move to the right and go down again
ny = ny + 80
if (ny == 1000) then
nx = nx + 300
ny = 280
end
-- Display students
student[row] = display.newText( sceneGroup, row.Name, nx, ny, native.systemFont, 30 )
--Make a button for every student in the row that goes to studentscene function
student[row]:addEventListener( "tap", studentscene)
end
The function then looks like
local function studentscene()
composer.gotoScene( "student", { time=800, effect="crossFade" } )
end
I want to be able to track which student name was pressed, yet i cannot find a way to do so. I need this so I can track in the database which name it is so I can display their information
you can add it by using params in goto function
`options = {
effect = model,
time = time,
params = params,
}
composer.gotoScene( nextScene , options )`
for example do this params = {student="mohsen"}
and in scene:show function do this :
if event.params then
studen = event.params.name
end

Outputting values not equal to certain values in yii2

I would like to output variables not equal to certain values but it returns an error of
Failed to prepare SQL: SELECT * FROM `tblsuunit` WHERE `unitid` != :qp0
There are two models the first model where am getting the array of ids
public function actionSunits($id){
$unitslocation = new Unitslocation();
$id2 = Unitslocation::find()->where(['officelocationid'=>$id])->all();
foreach( $id2 as $ids){
print_r($ids['unitid']."<br>");
}
}
This outputs the ids as
8
9
11
12
13
14
16
I would then like to take the id and compare another model(units model) and get the id values not similar to the above and output then
So i have added
$idall = Units::find()->where(['!=', 'unitid', $ids])->all();
So the whole controller action becomes
public function actionSunits($id){
$unitslocation = new Unitslocation();
$id2 = Unitslocation::find()->where(['officelocationid'=>$id])->all();
foreach( $id2 as $ids){
$idall = Units::find()->where(['!=', 'unitid', $ids])->all();
}
var_dump($idall);
}
This is the units model table:
If it were working it should return 7 and 10
What could be wrong..
You should fix your code and simply use a not in condition, e.g. :
// $uls will be an array of Unitslocation objects
$uls = Unitslocation::find()->where(['officelocationid'=>$id])->all();
// $uids will contain the unitids
$uids = \yii\helpers\ArrayHelper::getColumn($uls, 'unitid');
// then simply use a not in condition
$units = Units::find()->where(['not in', 'unitid', $uids])->all();
$idall = \yii\helpers\ArrayHelper::getColumn($units, 'unitid');
Read more about ActiveQuery::where() and ArrayHelper::getColumn().
Try with:
$idall = Units::find()->where(['not in','unitid',$ids])->all();
Info: https://github.com/yiisoft/yii2/blob/master/docs/guide/db-query-builder.md
operand 1 should be a column or DB expression. Operand 2 can be either
an array or a Query object.

Hive combine column values based upon condition

I was wondering if it is possible to combine column values based upon a condition. Let me explain...
Let say my data looks like this
Id name offset
1 Jan 100
2 Janssen 104
3 Klaas 150
4 Jan 160
5 Janssen 164
An my output should be this
Id fullname offsets
1 Jan Janssen [ 100, 160 ]
I would like to combine the name values from two rows where the offset of the two rows are no more apart then 1 character.
My question is if this type of data manipulation is possible with and if it is could someone share some code and explaination?
Please be gentle but this little piece of code return some what what I want...
ArrayList<String> persons = new ArrayList<String>();
// write your code here
String _previous = "";
//Sample output form entities.txt
//USER.A-GovDocs-f83c6ca3-9585-4c66-b9b0-f4c3bd57ccf4,Berkowitz,PERSON,9,10660
//USER.A-GovDocs-f83c6ca3-9585-4c66-b9b0-f4c3bd57ccf4,Marottoli,PERSON,9,10685
File file = new File("entities.txt");
try {
//
// Create a new Scanner object which will read the data
// from the file passed in. To check if there are more
// line to read from it we check by calling the
// scanner.hasNextLine() method. We then read line one
// by one till all line is read.
//
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
if(_previous == "" || _previous == null)
_previous = scanner.nextLine();
String _current = scanner.nextLine();
//Compare the lines, if there offset is = 1
int x = Integer.parseInt(_previous.split(",")[3]) + Integer.parseInt(_previous.split(",")[4]);
int y = Integer.parseInt(_current.split(",")[4]);
if(y-x == 1){
persons.add(_previous.split(",")[1] + " " + _current.split(",")[1]);
if(scanner.hasNextLine()){
_current = scanner.nextLine();
}
}else{
persons.add(_previous.split(",")[1]);
}
_previous = _current;
}
} catch (Exception e) {
e.printStackTrace();
}
for(String person : persons){
System.out.println(person);
}
Working of this piece sample data
USER.A-GovDocs-f83c6ca3-9585-4c66-b9b0-f4c3bd57ccf4,Richard,PERSON,7,2732
USER.A-GovDocs-f83c6ca3-9585-4c66-b9b0-f4c3bd57ccf4,Marottoli,PERSON,9,2740
USER.A-GovDocs-f83c6ca3-9585-4c66-b9b0-f4c3bd57ccf4,Marottoli,PERSON,9,2756
USER.A-GovDocs-f83c6ca3-9585-4c66-b9b0-f4c3bd57ccf4,Marottoli,PERSON,9,3093
USER.A-GovDocs-f83c6ca3-9585-4c66-b9b0-f4c3bd57ccf4,Marottoli,PERSON,9,3195
USER.A-GovDocs-f83c6ca3-9585-4c66-b9b0-f4c3bd57ccf4,Berkowitz,PERSON,9,3220
USER.A-GovDocs-f83c6ca3-9585-4c66-b9b0-f4c3bd57ccf4,Berkowitz,PERSON,9,10660
USER.A-GovDocs-f83c6ca3-9585-4c66-b9b0-f4c3bd57ccf4,Marottoli,PERSON,9,10685
USER.A-GovDocs-f83c6ca3-9585-4c66-b9b0-f4c3bd57ccf4,Lea,PERSON,3,10858
USER.A-GovDocs-f83c6ca3-9585-4c66-b9b0-f4c3bd57ccf4,Lea,PERSON,3,11063
USER.A-GovDocs-f83c6ca3-9585-4c66-b9b0-f4c3bd57ccf4,Ken,PERSON,3,11186
USER.A-GovDocs-f83c6ca3-9585-4c66-b9b0-f4c3bd57ccf4,Marottoli,PERSON,9,11234
USER.A-GovDocs-f83c6ca3-9585-4c66-b9b0-f4c3bd57ccf4,Berkowitz,PERSON,9,17073
USER.A-GovDocs-f83c6ca3-9585-4c66-b9b0-f4c3bd57ccf4,Lea,PERSON,3,17095
USER.A-GovDocs-f83c6ca3-9585-4c66-b9b0-f4c3bd57ccf4,Stephanie,PERSON,9,17330
USER.A-GovDocs-f83c6ca3-9585-4c66-b9b0-f4c3bd57ccf4,Putt,PERSON,4,17340
Which produces this output
Richard Marottoli
Marottoli
Marottoli
Marottoli
Berkowitz
Berkowitz
Marottoli
Lea
Lea
Ken
Marottoli
Berkowitz
Lea
Stephanie Putt
Kind regards
Load the table using below create table
drop table if exists default.stack;
create external table default.stack
(junk string,
name string,
cat string,
len int,
off int
)
ROW FORMAT DELIMITED
FIELDS terminated by ','
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
location 'hdfs://nameservice1/....';
Use below query to get your desired output.
select max(name), off from (
select CASE when b.name is not null then
concat(b.name," ",a.name)
else
a.name
end as name
,Case WHEN b.off1 is not null
then b.off1
else a.off
end as off
from default.stack a
left outer join (select name
,len+off+ 1 as off
,off as off1
from default.stack) b
on a.off = b.off ) a
group by off
order by off;
I have tested this it generates your desired result.