Search data from JSON string stored in DB - sql

I have a {"Name":[{"value":"First Name"}],"City":[{"value":"Delhi"},{"value":"London"]} varchar value stored in a column of db. I need to search every Person having city Delhi using JPQL. Is it good to store JSON string in db?

Well, substring matching can work for you in the most of the cases, but it's not precise and will be slow.
You can try something like that:
StringBuilder sb = new StringBuilder();
sb.append("SELECT table FROM Table table ");
sb.append("WHERE table.columnWithJson like '%\"City\":[%:city%]}' ");
Query q = em.createQuery(sb.toString())
q.setParameter("city", ""Delhi);
If you are using some database with support for regular expression and don't mind to abandon JPQL and use native query, this is an alternative for you too.

Related

Extract db objects dependencies from SSRS dataset with inline query (Query Type : Text)

I am dealing with a specific problem of identifying the dependent db objects for any SSRS RDL.
I have a good understanding of if any dataset have stored procedure as the query in a RDL then I can reference the associated stored procedure and get all the dependent objects (details can be found here: Different Ways to Find SQL Server Object Dependencies)
But I am looking specifically for the datasets with text query or inline query for any rdl. I am able to extract the CommandText from the XML of the rdl but I am not sure how to extract db objects like sp, table, views columns form a command text which is inline query in the rdl.
For example if I extract below query from XML commandText (this is a hypothetical query, names are not standardized in the database like vw_ for views , udf_ for functions):
-----This query serves Report ABC
SELECT DATE
,[amount]
,teamID = (SELECT TeamID FROM Sales.[getSalesPerson](r.date) as s WHERE R.[SalesPersonName] = S.[SalesPersonName])
,[channel]
,[product]
,[Item]
,r.[M_ID]
,Amount
,M.[Type]
FROM dbo.FactTable AS R
LEFT JOIN sp_Channel C ON R.[Channel_ID] = C.[Channel_ID]
LEFT JOIN Marketing.vw_M M ON R.[M_ID] = M.[M_ID]
Is there a way to identify that this query have dependent object as below:
ObjectName ObjectType
------------------------------------------
dbo.FactTable Table
sp_Channel Stored Procedure
Marketing.vw_M View
Sales.[getSalesPerson] Function
It is not easy to extract object names from an SQL command since they may be written in different ways (with/without schemas, databases name included ...)
But there are many option to extract objects from an SQL query that you can try:
Using Regular expressions, As example: You have to search for the words located after the following keywords:
TRUNCATE TABLE
FROM
UPDATE
JOIN
The following code is a C# example:
Regex regex = new Regex(#"\bJOIN\s+(?<Retrieve>[a-zA-Z\._\d\[\]]+)\b|\bFROM\s+(?<Retrieve>[a-zA-Z\._\d\[\]]+)\b|\bUPDATE\s+(?<Update>[a-zA-Z\._\d]+)\b|\bINSERT\s+(?:\bINTO\b)?\s+(?<Insert>[a-zA-Z\._\d]+)\b|\bTRUNCATE\s+TABLE\s+(?<Delete>[a-zA-Z\._\d]+)\b|\bDELETE\s+(?:\bFROM\b)?\s+(?<Delete>[a-zA-Z\._\d]+)\b");
var obj = regex.Matches(sql);
foreach(Match m in obj)
{
Console.WriteLine(m.ToString().Substring(m.ToString().IndexOf(" ")).Trim());
}
Output
Then you have to clean and join the result with the sys.objects tables from the SQL Server database.
Using a SQL parser, as example:
SQL Parser
SQL Parser - Code Project
You can refer to the following very helpful links for additional information:
Regular expression to find all table names in a query
Parsing SQL code in C#
If your reports are connecting to SQLServer and you have access you could try to get the execution plan with SET SHOWPLAN_XML ON and parse it.
Relevant thread for the parsing:extracting-data-from-sql-servers-xml-execution-plan

SqlQuery and SqlFieldsQuery

it looks that SqlQuery only supports sql that starts with select *? Doesn't it support other sql that only select some columns like
select id, name from person and maps the columns to the corresponding POJO?
If I use SqlFieldQuery to run sql, the result is a QueryCursor of List(each List contains one record of the result). But if the sql starts with select *, the this list's contents would be different with field query like:
select id,name,age from person
For the select *, each List is constructed with 3 parts:
the first elment is the key of the cache
the second element is the pojo object that contains the data
the tailing element are the values for each column.
Why was it so designed? If I don't know what the sql that SqlFieldsQuery runs , then I need additional effort to figure out what the List contains.
SqlQuery returns key and value objects, while SqlFieldsQuery allows to select specific fields. Which one to use depends on your use case.
Currently select * indeed includes predefined _key and _val fields, and this will be improved in the future. However, generally it's a good practice to list fields you want to fetch when running SQL queries (this is true for any SQL database, not only Ignite). This way your code will be protected from unexpected behavior in case schema is changed, for example.

How can I select a value from a database using Ruby and SQLite3?

I am having trouble returning a single value from a database using SQLite3 and Ruby.
A bit of context: I have a table of people and I would like to be able to query the database and get back the first name of someone in that table. I am using Rubymine with the SQLite3 gem.
When I run this code:
name = #db.execute <<-SQL
SELECT firstname FROM tbl_people WHERE email_address = '#{email_address}';
SQL
puts name
I get the following ouput:
{"firstname"=>"james", 0=>"james"}
When really the output I am expecting is:
james
If anyone can even point me in the right direction here it would be very much appreciated.
Cheers,
James
The execute() method creates a resultset, not just a single scalar value. You need to process the resultset to get the single value out of it.
name.each do |row|
puts row['firstname']
end
It sounds like you want to return the first value of the first row of a result set, and discard all other values and rows. The Database#get_first_value is what you want.
Also, for security you shouldn't inject strings into your SQL; allow the library to handle that for you.
query = "SELECT firstname FROM tbl_people WHERE email_address = ?;"
name = #db.get_first_value query, email_address
puts name

Store SQL query result (1 column) as Array

After running my query I get 1 column result as
5
6
98
101
Is there a way to store this result as array so that I can use it later
in queries like
WHERE NOT IN ('5','6','98','101')
I am aware of storing single variable results but is this possible?
I can not use #Table variable as I will be rerunning the query again in the future and it goes out of scope
There are multiple way of storing those column data like using Temporary Tables or View or Table valued function but IMO there is no need of storing that column data anywhere. You can directly use that column in any query saying below (or) perform a JOIN which would be much better option than NOT IN
select * from
table2
where some_column not in (select column1 from this_table);
While this method is not recommended, storing an array in a single column can be done using CSV's(Comma Separated Values). Simply create a VARCHAR array and store it by storing a string containing the values in a specific order. Basically store all of your values into a string with each value being separated by a comma in that string. Store that into a column of your choice. You can later fetch the string and parse it with a string parser i.e using the .split() function in python. AGAIN I do not recommend doing this, I would instead use multiple columns, one referring to each value and access them that way instead
Using separate columns would make it easy to use in a Stored Procedure.

Searching Database using LINQ

I have a database table (Access Database) that contains data under OrderNo field.
When user enters new OrderNo, I want to check if that OrderNo already exists or not.
If so, a message should be displayed.
How can I do it using LINQ?
Thanks
Furqan
You could do something like this:
int searchOrderNo;
searchOrderNo = 123;
var q = from t in db.MyTable
where t.OrderNo.Equals(searchOrderNo)
select t.OrderNo;
if (q.Count() > 0)
{
MessageBox.Show("Value already exists");
}
Apologies, as you are using Access I think you will need to populate a DataSet and then use LINQ over the DataSet rather than querying the Access DB directly.