Query From SQLite DataBase Android - cursor

I am trying to make a query from sqlite database by passing a value. Based on the passed value I need to fetch a unique record if data is available.Below is my code so far I have written
public String getDataOnlytransid(String Questionid)
{
String [] columns=new String[] {TRANS_ID};
Cursor c=ourDatabse.query(DATABASE_TABLE, columns, null,null,TRANS_ID,TRANS_ID + "=?", Questionid,null);
String result="";
int iRowID=c.getColumnIndex(TRANS_ID);
for(c.moveToFirst();!c.isAfterLast();c.moveToNext())
{
result=result + c.getString(iRowID); // n is for newline
}
c.close();
return result;
}
Then I am calling above method using below code
final question_savelistDB db = new question_savelistDB(context);
db.open();
final String question_id=db.getDataOnlytransid(dataList.get(position).getSaved_qid());
db.close();
But it is giving below error.What is the wrong I am doing
android.database.sqlite.SQLiteException: 1st ORDER BY term out of range - should be between 1 and 1 (code 1): , while compiling: SELECT trans_id FROM PaymentTable GROUP BY trans_id HAVING trans_id=? ORDER BY 2

The 7th argument of the method query() is the ORDER BY clause of the statement (without the ORDER BY keywords) and it should be a string.
Instead, you pass Questionid which is an integer and the ORDER BY clause becomes:
ORDER BY 2
You must pass the string TRANS_ID, which is the name of the one and only column that your query returns:
Cursor c = ourDatabse.query(DATABASE_TABLE, columns, null, null, TRANS_ID, TRANS_ID + "=?", TRANS_ID, null);
But, if the column TRANS_ID is unique in the table, you don't need the ORDER BY clause at all, since you expect 1 row at most in the results, so there is no need to sort and you could just pass null.
Also, you don't need the GROUP BY clause which is the 5th argument and instead of passing the parameter Questionid to a HAVING clause you should use the WHERE clause:
Cursor c = ourDatabse.query(DATABASE_TABLE, columns, TRANS_ID + "=?", TRANS_ID, null, null, , null, null);
Also, there is no need for a loop after you get the cursor.
You should only check if there is a row in the cursor and get the value of its only column:
public String getDataOnlytransid(String Questionid) {
String [] columns=new String[] {TRANS_ID};
Cursor c = ourDatabse.query(DATABASE_TABLE, columns, TRANS_ID + "=?", TRANS_ID, null, null, , null, null);
String result="";
if (c.moveToFirst()) result = c.getString(0);
c.close();
return result;
}
Also, you pass the parameter named Questionid for a column named TRANS_ID. Are you sure this is correct?
If it is, then I assume that you do it because you want to check if that Questionid exists in the table.
But you should know that getDataOnlytransid(), as it is, it returns the same value as Questionid if it exists in the table.

Related

OBJECT_CONSTRUCT function is not working properly

output--
I have written the query in snowflake to generate Json file, from the query output want to remove fields which has NULL. OBJECT_CONSTRUCT is not working properly for some column its not passing NULL value where else for some column its giving null value as result.
Input-
Json remove any field which has value NULL or blank.
{"DIFID":122,"DIF_FLAG":"NULL","DIF_TYPE":"asian/white","FOCAL_COUNT":2370,"REFERENCE_COUNT":17304},
Required Output-
Json remove any field which has value NULL or blank.
{"DIFID":122,"DIF_TYPE":"asian/white","FOCAL_COUNT":2370,"REFERENCE_COUNT":17304},
query-
select distinct ITEMSTATID,object_construct(
'DIFID',DIFID,
'DIF_TYPE',DIF_TYPE,
'DIF_FLAG',DIF_FLAG,
'FOCAL_COUNT',FOCAL_COUNT::integer,
'REFERENCE_COUNT',REFERENCE_COUNT::integer,
'DIF_METHOD',DIF_METHOD,
'DIF_VALUE',DIF_VALUE)
DIF
from DEV_IPM.STAGEVAULT.DIF_STATISTICS;
For string column and 'NULL' as string literal column's value is not skipped:
CREATE OR REPLACE TABLE DIF_STATISTICS
AS
SELECT 1 AS ITEMSTATID,
122 AS DIFID,
'NULL' AS DIF_FLAG, -- here
'asian/white' AS DIF_TYPE,
2370 AS FOCAL_COUNT,
17304 AS REFERENCE_COUNT;
Output:
The value is definitely stored as TEXT:
SELECT null AS DIF_FLAG, 'NULL' AS DIF_FLAG;
On the left: true NULL on the right: NULL string
If it the case then it should be nullified NULLIF(DIF_FLAG, 'NULL') before passing to OBJECT_CONSTRUCT function:
SELECT ITEMSTATID,
object_construct(
'DIFID',DIFID,
'DIF_TYPE',DIF_TYPE,
'DIF_FLAG',NULLIF(DIF_FLAG, 'NULL'),
'FOCAL_COUNT',FOCAL_COUNT::integer,
'REFERENCE_COUNT',REFERENCE_COUNT::integer) AS DIF
FROM DIF_STATISTICS;
Previous answer before column details were provided (also plausible):
It is working as intended:
NULL Values
Snowflake supports two types of NULL values in semi-structured data:
SQL NULL: SQL NULL means the same thing for semi-structured data types as it means for structured data types: the value is missing or unknown.
JSON null (sometimes called “VARIANT NULL”): In a VARIANT column, JSON null values are stored as a string containing the word “null” to distinguish them from SQL NULL values.
OBJECT_CONSTRUCT
If the key or value is NULL (i.e. SQL NULL), the key-value pair is omitted from the resulting object. A key-value pair consisting of a not-null string as key and a JSON NULL as value (i.e. PARSE_JSON(‘NULL’)) is not omitted.
For true SQL NULL values, that column is ommitted:
CREATE OR REPLACE TABLE DIF_STATISTICS
AS
SELECT 1 AS ITEMSTATID,
122 AS DIFID,
NULL AS DIF_FLAG,
'asian/white' AS DIF_TYPE,
2370 AS FOCAL_COUNT,
17304 AS REFERENCE_COUNT;
SELECT ITEMSTATID,
object_construct(
'DIFID',DIFID,
'DIF_TYPE',DIF_TYPE,
'DIF_FLAG',DIF_FLAG,
'FOCAL_COUNT',FOCAL_COUNT::integer,
'REFERENCE_COUNT',REFERENCE_COUNT::integer) AS DIF
FROM DIF_STATISTICS;
Output:
Probably the data type of the column DIFID is VARIANT/OBJECT:
CREATE OR REPLACE TABLE DIF_STATISTICS
AS
SELECT 1 AS ITEMSTATID,
122 AS DIFID,
PARSE_JSON('NULL') AS DIF_FLAG, -- here
'asian/white' AS DIF_TYPE,
2370 AS FOCAL_COUNT,
17304 AS REFERENCE_COUNT;
Output:

SQL Server: How to remove a key from a Json object

I have a query like (simplified):
SELECT
JSON_QUERY(r.SerializedData, '$.Values') AS [Values]
FROM
<TABLE> r
WHERE ...
The result is like this:
{ "2019":120, "20191":120, "201902":121, "201903":134, "201904":513 }
How can I remove the entries with a key length less then 6.
Result:
{ "201902":121, "201903":134, "201904":513 }
One possible solution is to parse the JSON and generate it again using string manipulations for keys with desired length:
Table:
CREATE TABLE Data (SerializedData nvarchar(max))
INSERT INTO Data (SerializedData)
VALUES (N'{"Values": { "2019":120, "20191":120, "201902":121, "201903":134, "201904":513 }}')
Statement (for SQL Server 2017+):
UPDATE Data
SET SerializedData = JSON_MODIFY(
SerializedData,
'$.Values',
JSON_QUERY(
(
SELECT CONCAT('{', STRING_AGG(CONCAT('"', [key] ,'":', [value]), ','), '}')
FROM OPENJSON(SerializedData, '$.Values') j
WHERE LEN([key]) >= 6
)
)
)
SELECT JSON_QUERY(d.SerializedData, '$.Values') AS [Values]
FROM Data d
Result:
Values
{"201902":121,"201903":134,"201904":513}
Notes:
It's important to note, that JSON_MODIFY() in lax mode deletes the specified key if the new value is NULL and the path points to a JSON object. But, in this specific case (JSON object with variable key names), I prefer the above solution.

Select on jsonb array on specific key/value

I have a jsonb field containing this data :
[{"FieldName":"wire1","Metadata":[{"Date":"2018-02-06T11:32:57.4022774+01:00","Source":"exampleSource"}]},
{"FieldName":"wire2","Metadata":[{"Date":"2018-02-06T11:32:57.4022774+01:00","Source":"exampleSource"}]},
{"FieldName":"wire3","Metadata":[{"Date":"2018-02-06T11:32:57.4022774+01:00","Source":"exampleSource"}]}]
What is the correct way to access the FieldName = FieldValue inside this array, as part of a select ? We tried SELECT meta::json->0 FROM myTable , and that returned null. (meta is the column's name containing the metaData)
What I hope to get is, in a select, to return all lines where FieldName = wire1, or where Source = exampleSource, or where both are true.
what you need is jsonb_array_elements function.
-> returns an object
SELECT jsonb_array_elements(**columnName**)->'FieldName' FROM ....
returns FieldName object
->> returns text
SELECT jsonb_array_elements(**columnName**)->>'FieldName' FROM ....
returns "wire1" text

DbString, IsFixedLength and IsAnsi for varchar

I am new to Dapper, want to know why below is suggested, when my code runs without it?
Ansi Strings and varchar
Dapper supports varchar params, if you are executing a where clause on
a varchar column using a param be sure to pass it in this way:
Query<Thing>("select * from Thing where Name = #Name", new {Name = new
DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi
= true });
On SQL Server it is crucial to use the unicode when querying unicode
and ansi when querying non unicode.
Below is my code, which runs against SQL server 2012 without using DbString etc.
create table Author (
Id int identity(1,1),
FirstName varchar(50),
LastName varchar(50)
);
go
insert into Author (FirstName, LastName) values ('Tom', 'John');
public Author FindByVarchar(string firstName)
{
using (IDbConnection db = DBHelper.NewSqlConnection())
{
return db.Query<Author>("Select * From Author WHERE FirstName = #firstName", new { firstName }).SingleOrDefault();
}
}
Questions:
1 Why is DbString type used in this case?
2 Why the length is set to 10 (e.g.Length = 10) when "abcde" is 5?
3 Do I still need to use DbString when my current code works?
4 Is it correct to set IsAnsi = false for unicode column?
5 For varchar column, is it correct to set IsFixedLength = false, and ignore setting Length?
The purpose of the example is that it is describing a scenario where the data type is char(10). If we just used "abcde", Dapper might think that nvarchar(5) was appropriate. This would be very inefficient in some cases - especially in a where clause, since the RDBMS can decide that it can't use the index, and instead needs to table scan doing a string conversion for every row in the table from char(10) to the nvarchar version. It is for this reason that DbString exists - to help you control exactly how Dapper configures the parameter for text data.
I think this answers your 1 and 2.
3: are you using ANSI (non-unicode text) or fixed-width text? Note that the ANSI default can also be set globally if you always avoid unicode
4: yes
5: yes
4+5 combined: if you're using nvarchar: just use string

Range parameter on the MDX-query

I have a correct MDX-query:
SELECT NON EMPTY { [Measures].[IssueOpened] } ON COLUMNS,
NON EMPTY { ([Projects].[Id].[Id].ALLMEMBERS * [Priorities].[Id].[Id].ALLMEMBERS ) } ON ROWS
FROM [Reports]
WHERE [CreatedOn].[Date].&[2010-01-01T00:00:00]:[CreatedOn].[Date].&[2010-02-01T00:00:00]
I need to create SSRS-report with filter on CreatedOn dimension.
Here is my non-working solution:
I transform query to:
SELECT NON EMPTY { [Measures].[IssueOpened] } ON COLUMNS,
NON EMPTY { ([Projects].[Id].[Id].ALLMEMBERS * [Priorities].[Id].[Id].ALLMEMBERS ) } ON ROWS
FROM (SELECT (STRTOSET(#CreatedOnDate, CONSTRAINED) ) ON COLUMNS
FROM [Reports])
CreatedOnDate parameter (type = datetime)
Set value of CreatedOnDate parameter to value:
="[CreatedOn].[Date].[" + Format(CDate(Parameters!CreatedOnDate.Value), "yyyy-MM-dd") + "T00:00:00]"
But when I run the report I get:
The restriction imposed by the CONSTRAINED flag in the STRTOSET function were violated
Somehow the parameter is not what you think. CONSTRAINED flag will force generating an error if the string is not a member when using StrToSet MDX function (check the failing example) :
You can try without the CONSTRAINED flag or find out the value of your parameter :
WITH
MEMBER myParam AS "[CreatedOn].[Date].[" +
Format(CDate(Parameters!CreatedOnDate.Value), "yyyy-MM-dd")
+ "T00:00:00]"
SELECT
[Measures].[myParam] on 0
FORM [Reports]
Playing a bit with this should make easier spotting the issue.
It should work if you use STRTOMEMBER for each side of the range
STRTOMEMBER("[CreatedOn].[Date].&[2010-01-01T00:00:00]", constrained):STRTOMEMBER("[CreatedOn].[Date].&[2010-02-01T00:00:00]", constrained)

Resources