SQL - Use object property as parameter for function - mysql

I am struggling to formulate the right sql-query to access the property of an object stored in one of my columns and use it as an input for a function:
I have a table 'search'
in 'search' one column is named 'coord' and stores POINT-Objects
I defined a function 'test' which gets a double-input parameter and just returns the input parameter as double
I want to make a query such as
SELECT test('coord.X') as res FROM `search` ORDER BY res
Expected result: The coord.X values listed in a columns named 'res' ordered from lowest to highest.
What I get is '0' for every entry (the coord X/Y values are of course set to arbitrary values).
If I leave the coord.X without the "'" around it the query fails with an error
#1054 - Unknown column 'coord.X' in 'field list'
I searched a lot but I couldnt find any pages telling me how to access properties of sql-objects. Any help is very much appreciated.

Consider your sample query without the test function.
SELECT coord.X as res FROM `search` ORDER BY res
Sql views coord.X as a column name and looks for that column in search. Since X is a property of coord, rather than part of the column name, this is what was causing your error.
Using
SELECT test(X(coord)) as res FROM `search` ORDER BY res
Should yield the correct results. Just as the syntax to call your test function is test(), the syntax to call the X function (defined in spacial extensions) is X(). However, this function will not work on columns that are not explicitly declared as a Point type because sql will not know how to parse the value and return the specified information.
Essentially, X() is similar to the many other mysql functions, such as ISNULL() or SUM(). Just as SUM() expects int data types as input, X() expects Point data types.

Shouldn't the query be:
SELECT coord as res FROM search ORDER BY res
Maybe I'm not understanding your question correctly.

Related

In MySQL, can I get the column type and and check column values in a single SELECT statement?

I'll start this off by saying I know that there are more practical ways to solve this. It's more of an intellectual curiosity than anything else.
I've inherited a MySQL database where some columns are stored as varchar(5) but actually contain the literals "True" or "False". Changing the structure of the data is not an option right now due to other issues. I'm mapping the columns to an ORM (SQLAlchemy), and I want the column to be mapped to a Boolean data type in the supporting codebase using a type adapter. (I've written this adapter already; it's not the problem.)
To help make the mapping process faster, I'm writing a small query to look at the INFORMATION_SCHEMA table and build a line of Python code defining the column using the ORM's syntax. I cannot assume that the data type varchar(5) is a Boolean column - I need to inspect the contents of that column to see if there are values contained in it besides True and False.
Can I write a query that will both get the column type from INFORMATION_SCHEMA and check the actual values stored in that column?
Here is the query I have so far:
SELECT CONCAT(
"Column(""",
col.column_name,
""", ",
(CASE
WHEN col.DATA_TYPE = "int" THEN "Integer"
-- Code in question
WHEN
col.DATA_TYPE = "varchar"
AND col.CHARACTER_MAXIMUM_LENGTH = 5
AND NOT EXISTS(
-- Doesn't seem to work
SELECT DISTINCT col.COLUMN_NAME
FROM col.TABLE_NAME
WHERE col.COLUMN_NAME NOT IN ("True", "False")
)
THEN "BoolStoredAsVarchar"
WHEN col.DATA_TYPE = "varchar" THEN CONCAT("String(", col.CHARACTER_MAXIMUM_LENGTH, ")")
-- Default if it's not a recognized column type
ELSE col.DATA_TYPE
END),
"),"
) AS alchemy
FROM information_schema.columns AS col
WHERE
col.TABLE_SCHEMA = "my_schema"
AND col.TABLE_NAME = "my_table"
ORDER BY col.ORDINAL_POSITION;
Running this code gives me a permissions error: Error Code: 1142. SELECT command denied to user 'user'#'host' for table 'table_name'. Presumably it's trying to use col.TABLE_NAME as a literal instead of interpreting it.
I've also tried creating a simple stored procedure and making table_name into a variable. However, replacing the FROM clause inside the EXISTS with a variable name gives me a syntax error instead.
Again, it's easy enough to run the query myself to see what's in that column. I'd just like to know if this is possible, and if so, how to do it.
You can't do what you're trying to do in a single query.
The reason is that table names (or any other identifier) must be fixed in the query at the time it is parsed, which is before it has read any values from tables. Thus you can't read the name of a table as a string from information_schema and also read from the table with that name in the same query.
You must read the table name from information_schema and then use that result to format a second query.
This isn't a problem specific to MySQL. It's true of any SQL implementation.

SSRS returned data type not valid for the aggregate function

I am making a SSRS, when executing the query
SELECT Brand.[KeyOffer],
COALESCE(SUM([Key Offer].Revenue),0) as Revenue
FROM [Brand Key Offer] Brand
LEFT JOIN [Key Offer] ON Brand.Keyoffer = [Key Offer].[Key Offer] AND [Key Offer].[Date] = '7/05/2017'
WHERE Brand.[Brand] = 'SMART'
GROUP BY [Brand].[KeyOffer]
ORDER BY [Revenue] DESC
But when I preview the reprot, I get this warning message.
Warning [rsAggregateOfInvalidExpressionDataType] The Value expression for the textrun ‘Textbox21.Paragraphs[0].TextRuns[0]’ uses an aggregate function with an expression that returned a data type not valid for the aggregate function. c:\users\t-aordiz\documents\visual studio 2015\Projects\TelemarketingRS\TelemarketingRS\Telemarketing Revenue.rdl 0
Ive been to a lot of topics but cant seem to find a way to solve this problem.
The same happened to me when I tried to change an output's datatype from datetime to varchar.
Try to delete the file YourReportFile.rdl.data and preview again. It worked for me in VS2015.
It looks like the error is being caused by the call to SUM(), possibly because you are feeding it a non numeric type. To test this, you could try casting [Key Offer].Revenue to decimal:
SELECT
Brand.[KeyOffer],
COALESCE(SUM(CAST([Key Offer].Revenue AS DECIMAL(10, 2))),0) AS Revenue
FROM [Brand Key Offer] Brand
...
You can use conversion in your expression to the appopriate type like below
= CDec(Fields!Revenue.value)
Also try the following SQL alternatives
COALESCE(SUM([Key Offer].Revenue),0.00)
or
CAST(COALESCE(SUM([Key Offer].Revenue),0) AS DECIMAL(10, 2))
(it's a little different from what Tim suggested)

how to escape single quotes in paramterised query

I have a problem. i am passing parameter in query using IN clause, but it is giving me error because instead of considering it as a two different values it is considering it as a one single value, so how can i handle this on sql level?
select * from table where name in ('abc','xyz'); this will work fine.
instead of this it is considering it as a
select * from table where name in ('abc,xyz'); this will give error
my parameter values are as below
basically i am checking conditional filtering. that why written this logic if values are there then consider this parameter in where clause or else ignore it.
case when '${thera}' <> '''' then
( ccp.name in ('${thera}') ) ELSE 1=1 END
Note : for avoiding conditional filtering any better approach is their then please suggest that to.
You can indeed pass a list of values as a parameter. But you need to use a Custom Parameter component.
For your example, you can create a Custom Parameter named parThera, and then for initial value you can use the expression as you would do in javascript:
['abc','xyz']
Another option is to use a function expression, like:
function (){
return "A list of words".split(" ");
}
Then, on the SQL query, add this parameter, using thera as argument name, and the parameter parThera as value.
Now you can use it inside the SQL like in your first example:
SELECT * FROM TABLE WHERE name IN (${thera})
The parameter will be expanded to 'abc','xyz', thus making it usable inside the IN (...) clause.
Note: on the SQL parameters setup, you need to specify that this parameter is of type StringArray. Otherwise it will not expand correctly.

how to sort varchar column containing numeric values with linq lambdas to Entity

I am using linq lambdas to query the MySql (Note MySql not Sql) with Entity Framwork in MVC. Now i have one table product one of column this table is price with datatype "VARCHAR" (Accept i can't change type to INT as it can hold values like "N/A",etc).
I want to sort price column numerically with linq Lambdas.I have tried bellow.I am using Model values to filter query.
var query = ent.Product.Where(b => b.cp == Model.CodePostal);
if (Model.order_by_flg == 2)
{
query = query.OrderByDescending(a => a.price.PadLeft(10, '0'));
}
But it will not work and give me bellow error.
LINQ to Entities does not recognize the method 'System.String
PadLeft(Int32, Char)' method, and this method cannot be translated
into a store expression.
As it cant convert to Sql statement by Entity Framwork.
I also tried bellow.
var query = ent.Product.Where(b => b.cp == Model.CodePostal);
if (Model.order_by_flg == 2)
{
query = query.OrderByDescending(a => a.price.Length).ThenBy(a => a.price);
}
But i can't do this because it works for List but i cant first make list and then do this as i am using linq Skip() and Take() so first i have to sort it.
So how can i sort price column of type "VARCHAR" in Linq lambda?
EDIT
In table it is :
59,59,400,185,34
Wnen i use OrderBy.ThenBy it gives
34,59,59,106,185,400
It looks right as sorting ascending But when i use OrderByDescending.ThenBy it gives
106,185,400,34,59,59
So i can't use this.
NOTE: Please give reasons before Downvote so i can improve my question...
You can simulate fixed PadLeft in LINQ to Entities with the canonical function DbFunctions.Right like this
instead of this
a.price.PadLeft(10, '0')
use this
DbFunctions.Right("000000000" + a.price, 10)
I haven't tested it with MySql provider, but canonical functions defined in the DbFunctions are supposed to be supported by any provider.
It looks right as sorting ascending But when i use OrderByDescending.ThenBy it gives
106,185,400,34,59,59
That's because you're ordering by length descending, then value ascending.
What you need is simply to sort both by descending;
query = query.OrderByDescending(a => a.price.Length)
.ThenByDescending(a => a.price);
This should be faster than prepending numbers to sort, since you don't need to do multiple calculations per row but can instead sort by existing data.

solr: Create filter query with a function

One of the values returned by my solr query is a calculated value (using solr 4.0). The function is
sum(product(2,preis12_0_3),preis34_0_3)
Now I would like to filter the resultset on the values returned by the function, but I get this error:
undefined field text
Is it possible to filter on a function? Any pointers in the right direction appreciated.
Filter query do support function queries with FunctionRangeQParserPlugin
e.g. Filter query example: fq={!frange l=0 u=2.2}sum(user_ranking,editor_ranking)
undefined field text -> Would be the case for the field not being defined in the schema.xml