Creating a Kusto table with table name coming from query result - azure-data-explorer

I would like to create a table the name of which comes from result of a query. Any very basic example will do. The result could be a single column , single row also. I just need a basic example so I can tweak and modify it as per my requirement.

any control command which creates a table requires the table name to be known in advance and part of the command's text.
you could run a 2-step flow programmatically, where:
the 1st step gets the table name (e.g. using a query),
the 2nd step generates the .create table or .set command string (based on the 1st), then invokes the command.
an example, using the .NET client library:
using Kusto.Data;
using Kusto.Data.Common;
using Kusto.Data.Net.Client;
using System.Linq;
namespace Playground
{
class Program
{
static void Main(string[] args)
{
const string clusterName = "myClusterName";
const string regionName = "westus";
const string databaseName = "myDatabaseName";
const string queryForTableName = "MyExistingTable | summarize count() by TableName | top 1 by count_ desc | project TableName";
var kcsb = new KustoConnectionStringBuilder($"https://{clusterName}.{regionName}.kusto.windows.net", databaseName).WithAadUserPromptAuthentication();
using (var queryProvider = KustoClientFactory.CreateCslQueryProvider(kcsb))
{
// step 1: get the table name, based on the result of a query
var tableName = queryProvider.ExecuteQuery<string>(queryForTableName).Single();
using (var adminProvider = KustoClientFactory.CreateCslAdminProvider(kcsb))
{
// step 2.1: generate the control command's text, using the value from step 1
var createTableCommand = CslCommandGenerator.GenerateTableSetCommand(tableName, "print value = 'This is a value in my new table'", isAsync: false);
// step 2.2: invoke the control command
adminProvider.ExecuteControlCommand(createTableCommand);
}
}
}
}
}

Related

.Net Core Npgsql Return Single Row

I was just wondering if it's possible to return a single row using Npgsql in a .Net Core Script.
I've been doing with the Read Method like bellow
NpgsqlCommand command = new NpgsqlCommand (
" select col01, col02, col03 from table ",
dbconnection
);
var result = command.ExecuteReader();
while(result.Read()) {
var varCol01 = result["col01"];
var varCol02 = result["col02"];
}
Which seems a bit excessive for a single row because I would have to exit the while manually.
Each time you call NpgsqlDataReader.Read, you're reading an additional row - so your code sample doesn't seem to be a good fit for a single row scenario...
If you know you're only getting a single row, why not do something along the lines of:
var reader = command.ExecuteReader();
reader.Read(); // You can do a Debug.Assert to make sure the result of this is true
var (col1, col2) = (result["col01"], result["col02"]);

ASP.NET my Linq code for nullable DateTime comparison is failing

My app allows user to upload an XML file, which I pass as an XDocument into my method. All the values are attribute strings, and I am using Linq to XML and Linq to SQL.
The dateCutoff query is supposed to get the latest date from SQL table - InsDate is nullable.
The where clause in the inspections XML query is supposed to get inspection elements with the inspection_date attribute value later than the dateCutoff value. I am using DateTime.Parse and Date.CompareTo, but am coming up empty.
What am I missing? Any help is much appreciated.
public IEnumerable<XElement> getInspections(XDocument xDoc)
{
IEnumerable<XElement> inspections = null;
using (InspectionDataContext db = new InspectionDataContext())
{
// get the latest date already in Inspections table
DateTime? dateCutoff = (from d in db.Inspections
select d.InsDate).Max();
if (dateCutoff.HasValue)
{
dateCutoff = dateCutoff.Value.Date;
}
// get only the inspections later than the dateCutoff
inspections = from i in xDoc.Descendants("inspections")
where DateTime.Parse(i.Element("inspection").Attribute("inspection_date").Value).Date.CompareTo(dateCutoff) == 1
select i;
}
return inspections;
}
I'm gong to make a few assumptions here because it's not totally clear as written.
1. You want to return "inspection" elements (not the "inspections" container elements).
2. You want to return only elements whose dates are greater than the cutoff
3. If the cutoff is null, you want to return all inspections.
In that case, you'd do something like this:
var inspections = xDoc.Descendents("inspection");
if (!dateCutoff.HasValue)
return inspections;
return inspections.Where(i => (DateTime)i.Attribute("inspection_date") > dateCutoff.Value )
Here is what works:
DateTime? dateCutoff;
using (InspectionDataContext db = new InspectionDataContext())
{
// get the latest date already in Inspections table
DateTime? dateCutoffQ = (from d in db.Inspections
select d.InsDate).Max();
if (dateCutoffQ.HasValue)
{
dateCutoff = dateCutoffQ.Value.Date;
}
else
{
dateCutoff = DateTime.Now.AddYears(-20).Date;
}
string date1 = dateCutoff.ToString();
// get only the inspections later than the dateCutoff
inspectionList = from i in xDoc.Descendants("inspection")
where DateTime.Parse(i.Attribute("inspection_date").Value).Date > dateCutoff
select i;

Split the string of a row of datatable in asp.net

I am using asp.net. I am trying to split the data which is in datatable. I have a code sample like this:
{ dt=objErrorLoggingDataAccess.GetErrorDetails(errorID);
string[] stringSeparators = new string[] { "Message" };
string error = dt.Rows[0]["Message"].ToString();
string[] test = error.Split(stringSeparators, StringSplitOptions.None);
string PageName = test[0].ToString();
PageNameLabel.Text = PageName;
stringSeparators=new string[] {HttpContext.Current.Request.Url.ToString()};
error = dt.Rows[0]["Message"].ToString();
test = error.Split(stringSeparators, StringSplitOptions.None);
string Message = test[0].ToString();
MessageLabel.Text = Message;}
in the datatable following data is there:
{....ID.......Message.......................................................................................................................
....1........http://localhost:10489/images/CategoryIcon/images Message : File does not exist. UserName: naresh#naresh.com
....2........http://localhost:10489/images/CategoryIcon/images Message : File does not exist. UserName: iswar#iswar.com}
My problem is: how can I split the Message and store in the label? I want
{http://localhost:10489/images/CategoryIcon/images}
separately and UserName separately and the message separately. How can I do that? By executing the above code I am able to split
{ http://localhost:10489/images/CategoryIcon/images
}
only. How can I split the Message column and store in pageLabel, MessageLabel, UserNamelabel?
I would use a regular expression in this case. Because only by splitting this string looks a little bit to inflexible to me.
I tested your data example against this quick and dirty RegEx:
(?<id>\d+)\.*(?<url>\w+:\/\/[\w#][\w.:#]+\/?[\w\.?=%&=\-#/$,]*)\s*Message\s*:\s*(?<message>.*)UserName:\s*(?<username>([a-zA-Z0-9_\-\.]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3}))
It supports valid URLs and EMail patterns.
Regex regex = new Regex(
"(?<id>\\d+)\\.*(?<url>\\w+:\\/\\/[\\w#][\\w.:#]+\\/?[\\w\\.?"+
"=%&=\\-#/$,]*)\\s*Message\\s*:\\s*(?<message>.*)UserName:\\s"+
"*(?<username>([a-zA-Z0-9_\\-\\.]+)#((\\[[0-9]{1,3}\\.[0-9]{1"+
",3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|"+
"[0-9]{1,3}))",
RegexOptions.IgnoreCase
| RegexOptions.CultureInvariant
| RegexOptions.IgnorePatternWhitespace
| RegexOptions.Compiled
);
// Capture the first Match, if any, in the InputText
Match m = regex.Match(InputText);
// Capture all Matches in the InputText
MatchCollection ms = regex.Matches(InputText);
// Test to see if there is a match in the InputText
bool IsMatch = regex.IsMatch(InputText);
// Get the names of all the named capture groups
// I included your fields as groups: id, url, message and username
string[] GroupNames = regex.GetGroupNames();
I don't know how often you need to call this code. Maybe you get in performance troubles if you have too much data. This regex is q&d - please adjust it to your needs.

Faster database access by index

I have this code
using (var contents = connection.CreateCommand())
{
contents.CommandText = "SELECT [subject],[note] FROM tasks";
var r = contents.ExecuteReader();
int zaehler = 0;
int zielzahl = 5;
while (r.Read())
{
if (zaehler == zielzahl)
{
//access r["subject"].ToString()
}
zaehler++;
}
}
I want to make it faster by accessing zielzahl directly like r[zielzahl] instead of iterating through all entries. But
r[zielzahl]["subject"]
does not work aswell as
r["subject"][zielzahl]
How do I access the column subject of result number zielzahl?
To get only the sixth record, use the OFFSET clause:
SELECT subject, note
FROM tasks
LIMIT 1 OFFSET 5
Please note that the order of returned records is not guaranteed unless you use the ORDER BY clause.

How use a variable name to point different data types with the same name?

I have 2 List one stores the name of filterable columns(of type DropDown) and another store the values to load in those filterable columns.
List<string> filterableFields = new List<string>() { "A_B", "C_D", "E_F" };
List<string> AB, CD , EF;
Now at the run time I get the data from web service and I have written a function to to extract values for these filterable fields and store the values to 2nd List.
private void prepareListForFilterableColumns(XDocument records)
{
foreach (var currentField in filterableFields)
{
var values = (from xml in records.Descendants(z + "row")
let val = (string)xml.Attribute("ows_" + currentField.Replace("_", "_x0020_"))
where val != ""
orderby val
select val
).Distinct();
switch (currentField)
{
case "A_B": AB = values.ToList(); break;
case "C_D": CD = values.ToList(); break;
}
}
}
Now I was thinking that instead of hard coding the assignment in swtich case block, If I could just use the first List name "A_B" and replace "_" from it to point to my 2nd List and assign values.ToList() to it.
I understand that c# is a static language, So not sure if we can achieve this, but IF I can it will make my function generic.
Thanks a lot in advance for time and help.
Vishal
You could use a dictionary of lists of strings instead of 3 lists to store the values.
Dictionary<string, List<string>> val lists = new Dictionary<string,List<string>>();
And make the keys of the dictionary equal to the filterables: "AB", "CD",..
then, instead of AB you would use valLists["AB"] and could then reference reach list based on a string key.
The other option would be to use reflection but that would be slower and unnecessarily a bit more complicated.

Resources