Kusto tabular arguments with multiple columns - azure-data-explorer

How do I properly define and invoke a user function with an argument of tabular type which has multiple columns?
This page does not have any examples of that sort - https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/functions/user-defined-functions#features-that-are-currently-unsupported-by-user-defined-functions
To provide some context for my question, here is my attempt for doing this
let foo=(T1:(col1:string, col2:string))
{
T1|count // something more complex will go here,
// so just avoiding the whole function is not an option.
}
someTable | summarize Res=foo(Col1, Col2) by Col3, Col4
Here Kusto recognizes my function, but complains about it accepting only one argument.
How can I go about passing two columns to it?
Thanks,
Dusan

This is not possible, you cannot invoke a user-defined function as a summarize function, the list of summarization functions is defined by the Kusto Query Language and currently cannot be extended.
Within a query, a function that accepts a tabular input can only be invoked using the invoke operator

Related

Passing multiple values as parameter to teradata view [duplicate]

This question already has an answer here:
Teradata variable with list of values
(1 answer)
Closed 3 years ago.
We are trying to pass values from report to teradata view as parameter. How do we pass multiple values to teradata view ?
AND (v_fact_xyz in (?) or 'ALL' in (?))
is the line of code written currently
where ? can be single value('Abd, EFG(ORM)') or multiple values like these
The report is working fine with single parameter passed but throws error while passing multiple values
.net data provider for teradata 110083 error.
A Null has been specified as the value for a parameter
If I understand correctly, your question is how to pass multiple values to your IN clause, something like this:
SELECT *
FROM MyView
WHERE v_fact_xyz IN ('Abd','EFG(ORM)','AnotherValue')
If that's the case, one way to do it is using a "split" UDF (user-defined function) to convert your parameter string into a format that the IN clause supports. The IN clause can take record-sets or a single value, but not a comma-separated list.
This page may give you some ideas:
https://web.archive.org/web/20211020153409/https://www.4guysfromrolla.com/webtech/031004-1.shtml
Also check to see if Teradata offers any built-in "split" or "delimited" UDFs which you can use to do this.

Is there a way to display dynamic columns in Oracle apex

Long story short, I can't use pivot for this task due to the long elements that I need to include in the columns. Although I tried to create a Classic Report based on function in Oracle Apex. The query it's generated correctly but it's not working in the Classic Report.
A general hint first: Output your variable l_sql to your console using dbms_output.put_line or use some kind of debugging table where you can insert it into. Also be careful about the data type of that variable. If you need to expand the SQL you can reach a point where you need to use a CLOB variable instead of varchar2.
You will need to supply table structures and test data if you like to have your problem analyzed completely, therefore I will at first give you some general explanations:
Use Generic Column Names is ok if you have a permanent, unchangable amount of columns. But if the order of your columns or even the amount can change, then this is a bad idea, as your page will show an error if your query results in more columns than Generic Column Count
Option 1: Use column aliases in your query
Enhance your PL/SQL Function Body returning SQL Query in a way that it outputs verbose display names, like this:
return 'select 1 as "Your verbose column name", 2 as "Column #2", 3 as "Column #3" from dual';
That looks like this:
It has the disadvantage that the column names also appear in this way in the designer and APEX will only update these column names if you re-validate the function. You will have a hard time to reference a column with the internal name of Your verbose column name in a process code or dynamic action.
However it still works, even if you change the column names without telling APEX, for example by externalizing the PL/SQL Function Body into a real function.
Option 2: Use custom column headings
A little bit hidden, but there is also the option of completely custom column headings. It is almost at the end of the attributes page of your report region.
Here you can also supply a function that returns your column names. Be careful that this function is not supposed to return an SQL query that itself returns column names, but instead return column names seperated by a colon.
With this method, it is easier to identify and reference your columns in the designer:
Option 3: Both of it
Turn off Generic Column Names, let your query return column names that can be easily identified and referenced, and use the custom column headings function return verbose names for your users.
My personal opinion
Im using the 3rd option in a production application where people can change the amount and order of columns using shuttle items on the report page themselves. It took some time, but now it works like a charm, like some dynamic PIVOT without PIVOT.

Not able to have commands in User-Defined functions in Kusto

I am trying to create a function that will accept name of tag and a datetime value and drop a extent within a specific table which has that tag and then ingest a new record into that table with the same tag and the input datetime value -- sort of 'update' simulation. I am not bothered about performance, it's just going to hold metadata -- maybe 20-30 rows at max.
So this is how the create table looks:-
.create table MyTable(sometext:string,somevalue:datetime)
And shown below is my function creation step, which is failing:-
.create-or-alter function MyFunction(arg_sometext:string,arg_somedate:datetime)
{
.drop extents <| .show table MyTable extents where tags has arg_sometext;
.ingest inline into table MyTable with (tags="[arg_sometext]") <| arg_somedate
}
So you can see I am trying to do something simple -- I am suspecting that Kusto won't allow commands in a function. Is there any workaround for achieving this?
Generally:
Kusto mandates that control commands start with a dot (.), and that this must be the first character in the text of the command. As queries, functions, etc. don't start with a dot, this precludes them from invoking control commands.
This is an intentional limitation that prevents a wide range of code injection attacks. By imposing this rule, Kusto makes it easy to guarantee that any query that does not begin with a dot will only have read access to the data and metadata, and never be able to alter them.
Specifically: with regards to your specific scenario:
I'm assuming it's triggered automatically (even if you did have the option to create a function), which suggests you should be able to achieve your goal using Kusto's API / Client libraries and a simple script/app.
An alternative, and perhaps even better approach, would be to re-consider if you actually need to delete or update specific records, or you can use summarize arg_max() in order to query for only the latest "versions" of the records (you could also create a function which encapsulates that logic and overrides the table, by naming the function with the table's name).

Use SOUNDEX function in Websql

I'm trying to include this function in a websql query, something like
"select * from products where filter like '%pname%' order by soundex(filter);"
But according to this: https://www.sqlite.org/lang_corefunc.html
Soundex function is only available if sqlite was compiled with SQLITE_SOUNDEX argument, which I don't think is the case for chrome as is throwing
could not prepare statement (1 no such function: soundex)
So, my question is, is there a way to use soundex function, or at least some other similar function?
Edit 1:
For now I'm just using
order by coalesce(like('pname', filter), 0)
which is not the final solution, but better than a simple order by a specific column.
WebSQL does not specify which SQL functions are available, and has no mechanism to install user-defined functions.

Common table expression functionality in SQLite

I need to apply two successive aggregate functions to a dataset (the sum of a series of averages), something that is easily and routinely done with common table expressions in SQL Server or another DBMS that supports CTEs. Unfortunately, I am currently stuck with SQLite which does not support CTEs. Is there an alternative or workaround for achieving the same result in SQLite without performing two queries and rolling up the results in code?
To add a few more details, I don't think it could be easily done with views because the first set of aggregate values need to be retrieved based on a WHERE clause with several parameters. E.g.,
SELECT avg(elapsedTime)
FROM statisticsTable
WHERE connectionId in ([lots of values]) AND
updateTime > [startTime] AND
updateTime < [endTime]
GROUP BY connectionId
And then I need the sum of those averages.
Now that we are in THE FUTURE, let me note here that SQLite now does support Common Table Expressions, as of version 3.8.3 of 2014-02-03.
http://www.sqlite.org/lang_with.html
Would this work?
SELECT SUM(t.time) as sum_of_series_of_averages
FROM
(
SELECT avg(elapsedTime) as time
FROM statisticsTable
WHERE connectionId in ([lots of values]) AND
updateTime > [startTime] AND
updateTime < [endTime]
GROUP BY connectionId
) as t
By converting your averages into an inline view, you can SUM() the averages.
Is this what you are looking for?
As you've mentioned, SQLite doesn't support CTEs, window functions, or any of the like.
You can, however, write your own user functions that you can call inside SQLite by registering them to the database with the SQLite API using sqlite_create_function(). You register them with the database, and then you can use them in your own application code. You can make an aggregate function that would perform the sum of a series of averages based on the individual column values. For each value, a step-type callback function is called that allows you to perform some calculation on the data, and a pointer for holding state data is also available.
In your SQL, then, you could register a custom function called sum_of_series_of_averages and have:
SELECT sum_of_series_of_averages(columnA,columnB)
FROM table
WHERE ...
For some good examples on how those work, you should check out the SQLite source code, and also check out this tutorial (search for Defining SQLite User Functions).

Resources