Using relative paths within SQL XQuery arithmetic - sql-server-2008-r2

Is there a simple way to use a relative path within XQuery arithmetic within SQL Server?
e.g. with the below code, I'm repeating /a/b/ on both sides of the operator:
declare #x xml = '<a><b><x>10</x><y>20</y></b></a>'
select #x.value('((/a/b/x/text())[1] + (/a/b/y/text())[1])[1]','bigint')
More Info
NB: I'm aware that in the example above I could use the SUM function... Sadly that would not apply to my real use case, where I have multiple elements with various operations to be performed between them.
I'm also familiar with the nodes option to do something like below:
select ab.b.value('((./x)[1] + (./y)[1])[1]','bigint')
from #x.nodes('/a/b') ab(b)
I'm also familiar with using outer apply/cross apply to access such subqueries when the XML is coming from a column rather than a variable. That's currently the route I'm taking, but it feels a little clunky.
I'm visualising a solution similar to this:
select #x.value('(/a/b[(./x)[1] + (./y)[1]])[1]','bigint'); i.e. similar to how a filter can be applied to multiple elements within the context of the current path; but haven't found how that would be written (assuming this is even possible).

declare #x xml
SET #x = '<a><b><x>10</x><y>20</y></b></a>'
select #x.query('
for $i in /a/b
return
data($i/x[1]) + data($i/y[1])
')
If the path is too long and you want to use an "alias" for it, the above can be an option. It may look nicer a bit? You can replace + by other operators such as -, *,etc. (tested with SQL server 2005)

In most XQuery systems, given your data, you can replace
'((/a/b/x/text())[1] + (/a/b/y/text())[1])[1]'
with
'/a/b/(x+y)'
But I believe the SQL server implementation has its own quirks so this might not apply in your case. If you need a way to get around pessimistic type checking then
/a/b/sum((x,y))
might do the trick.

Related

Reading CSV file with Spring batch and map to Domain objects based on the the first field and then insert them in DB accordingly [duplicate]

How can we implement pattern matching in Spring Batch, I am using org.springframework.batch.item.file.mapping.PatternMatchingCompositeLineMapper
I got to know that I can only use ? or * here to create my pattern.
My requirement is like below:
I have a fixed length record file and in each record I have two fields at 35th and 36th position which gives record type
for example below "05" is record type which is at 35th and 36th position and total length of record is 400.
0000001131444444444444445589868444050MarketsABNAKKAAAAKKKA05568551456...........
I tried to write regular expression but it does not work, i got to know only two special character can be used which are * and ? .
In that case I can only write like this
??????????????????????????????????05?????????????..................
but it does not seem to be good solution.
Please suggest how can I write this solution, Thanks a lot for help in advance
The PatternMatchingCompositeLineMapper uses an instance of org.springframework.batch.support.PatternMatcher to do the matching. It's important to note that PatternMatcher does not use true regular expressions. It uses something closer to ant patterns (the code is actually lifted from AntPathMatcher in Spring Core).
That being said, you have three options:
Use a pattern like you are referring to (since there is no short hand way to specify the number of ? that should be checked like there is in regular expressions).
Create your own composite LineMapper implementation that uses regular expressions to do the mapping.
For the record, if you choose option 2, contributing it back would be appreciated!

Why use result sets rather than variables in Sybase?

In a Sybase database I am working with result sets are used (misused?) as variables.
For example, one often finds lines such as the following:
select SOMETHING = 'bla'
"SOMETHING" is technically a result set ... and the content of the result set is used by the application accessing the database. Since "SOMETHING" is not a variable, it does not get declared anywhere.
I have never seen this kind of hack before (and colleagues of mine couldn't explain to me the reason why it was done that way) and I have not found anything about it on google.
Is there some reference available that explains why one would want to use such a hack as opposed to "normal" variables?
I think you are not reading this correctly. This query simply means that there is a one-column result set with the column named 'SOMETHING'. This query is equivalent to: SELECT 'bla' AS SOMETHING

How to know if a PostfixExpression belongs to a for statement?

I'm using eclipse parser to work with expressions and statements in java code.
I have a function:
public boolean visit(PostfixExpression node)
which deals with Postfix expressoins, such ass i++;
Problem is i want to distinguish between a for statement postfix, and other postfixes.
I thought maybe i could get to the node's parent and somehow check if it's a for. Something like node.getParent()... but node.getParent() doesn't return an expression.
Any ideas how to recognize if the PostfixExpression belongs to a for loop?
Thanks
edit:
By "for statement postfix" i mean the postfix in the for loop's first line. Such as:
for(i=0;i<10;i++)
So i want to distinguish this i++ from other i++'s.
Can't you just call ASTNode.getParent() to see what kind of statement the expression is contained in?
I solved this by creating a for_updaters List (using node.updaters()) and updating it every time i visit a for loop (could also be nested loops). Also, whenever i come across a PostfixExpression (including for updaters), i add it to another List, and then delete from this List all similar occurrences that appear in for_updaters List. This way i'm only left with non-for-updaters Postfixes. This also works for me because every time i visit a for loop i clear both Lists, so no worries about duplicate variable names.
Note: node.updaters() returns the exact full expression: [i++]. But i only need i. It's easy to extract it by converting the updater to String and then use substring().

Calling PL/pgSQL function ignoring results

I like to call a stored PL/pgSQL function the same way as with PERFORM ignoring the results, but from plain SQL. How can i achive this? I'm currently using SELECT to execute the function, but this prints data on the console what i don't need.
I thought about disabling client output for specific SELECT statements, but i can't find any client settings for this. Maybe there's a better way to do this kind of calls.
There is no such functionality in plain sql. What you can do though, is make the function not return anything.
Here is a dirty hack, i just came up with;
background is, i need to call a function, but specify an UPDATE, not a SELECT ...maybe your background is the same...
So I specified my UPDATE like this:
UPDATE sometable_doesnt_matter
SET some_comlumn=some_comlumn
WHERE (select my_function = 1);
And my function always returns the integer 1.
Ofc i'm going to change the code so that it will also work with a SELECT, but right now, as a hotfix, this works for me.

How to prevent SQL injection if I don't have option to use "PreparedStatement" in Java/J2EE

I have one application In which I can’t user “PreparedStatement” on some of places.
Most of SQL queries are like….
String sql = "delete from " + tableName;
So I like to know how to fix “SQL Injection” problem in my code.
Regards,
Sanjay Singh
=======================Edited After getting answer and like to verify solution==========
According to provided suggestion I have identified one strategy to prevent SQL injection in my case ….
Like to know views, I am working on the VeraCode Certificate for our application…
Filter Data so it does not content any space and escape SQL character (so if there is any injected code,
it’ll not going to part of my dynamic SQL, so my column name and table name can’t use to inject SQL query).
public static String getTabColName(String tabColName)
{
if(tabColName == null || "".equals(tabColName.trim()))
return "";
String tempStr = StringEscapeUtils.escapeSql(tabColName.trim());
//If this value content space that means it is not a valid table
// or column name, so don’t use it in dynamic generated SQL
//use space so it create an invalid SQL query
return tempStr.indexOf(' ') == -1 ? tempStr : "";
}
Parameterised queries are a major step towards preventing SQL injection attacks. If you cannot use them, you have an equally major setback in your hands. You can somewhat mitigate the danger by:
input string validation. And I mean validation with all the bells and whistles, which can sometimes reach the level of a full-blown parser, not just a few checks.
input manipulation (e.g. quoting and string escaping). Again, you have to do this right, which can be harder than it seems.
Both techniques are problematic - you have to let valid input through unchanged, in order to maintain compatibility with your current codebase, while still effectively protecting your system. Good luck with that...
From my experience, refactoring - or even rewriting - your code to use prepared statements will save you a lot of time and tears in the long run.
If you don't have a peer-reviewed library of string-escaping functions, at the very least you should white-list characters that you know are safe to embed in strings. For instance, ensure your strings are composed only of letters, digits and underscores, and nothing else. Black-listing known "bad characters" is poised to get you in trouble.
Making sure that the input contains only allowed characters is just an important first step. Your sample statement is a good example for the value of the strategy "find input in a list of all good values" (you surely know the set of tables in your database and the subset of tables users are allowed to zap). "compare input against plausible range" (salary shouldn't be increased by millions or half cents), or "match input against a regex to reveal structural violations" are further examples.
To get confidence in your defenses, you may consider using a QuickCheck-like testing library to attack your validation functions by (suitably biased) random strings. This article lists implementations for languages other than Haskell.