Does calling a user defined function twice in select query lead to inefficiency? - sql

I have a simple table where people's birthday are been stored. I also have a simple scalar user defined function where the function takes a "Date" object (birthday) and returns an int (Age). I wrote a query which tries to select every entry that has an age of 17.
In the "select" query, "dbo.calculateAge(Birthday)" were written twice, so I was just wondering, does this mean that "calculateAge" function will be called twice? Does this leads to inefficiency? If yes, is there a better way to write this query?
My Query:
My Table:
I choose not to include implementation of the "calculateAge" function here because I don't think it is useful to the question I'm asking.

does this mean that "calculateAge" function will be called twice?
No, just once. But to be sure, make sure your function is declared as deterministic.
Does this leads to inefficiency?
No.
If yes, is there a better way to write this query?
It's fine.

Related

How to cache return value of a function for a single query

I want to use getdate() function 3-4 times in my single query for validation check. But I want that everytime I anticipate to get current datetime in a single query execution I get the same date at all 3-4 places. Not technically computers are that fast that 99.9% times I will get the same datetime at all places in query. But theoretically it may lead to bug. So how can cache that getdate return by calling it once and use that cached values in query.
But to add, I want to write such statement in check constraint, so I cant declare local variables, or any such thing.
SQL Server has the concept of run-time constant functions. The best way to describe these is that the first thing the execution engine does is pull the function references out from the query plan and execute each such function once per query.
Note that the function references appear to be column-based. So different columns can have different values, but different rows should have the same value within a column.
The two most common functions in this category are getdate() and rand(). Ironically, I find that this is a good thing for getdate(), but a bad thing for rand() (what kind of random number generator always returns the same value?).
For some reason, I can't find the actual documentation on run-time constant functions. But here are some respected blog posts that explain the matter:
https://sqlperformance.com/2014/06/t-sql-queries/dirty-secrets-of-the-case-expression
http://sqlblog.com/blogs/andrew_kelly/archive/2008/03/01/when-a-function-is-indeed-a-constant.aspx
https://blogs.msdn.microsoft.com/conor_cunningham_msft/2010/04/23/conor-vs-runtime-constant-functions/

SQL Parameterized Query with Names instead of Question Marks

Question:
Is there a way to use names instead of question marks for paramaterized queries? If so, can anyone suggest some material that explains how to do this/the syntax?
A bit more detail:
For example, if I have something like:
INSERT INTO inventory VALUES(?)
Is it possible to have something like this instead that does the exact same thing as the question mark:
INSERT INTO inventory VALUES("prices")
I tried checking to see if it would work myself before posting the question, but it didn't work. So, I thought I'd ask if it was possible.
I feel like if you have a really long query with, let's say 20 parameters, you don't want to have to count question marks to make sure you have enough parameters whenever you change something. Also, I think it might make the code a bit more readable (especially if you have a lot of parameters to keep track of).
I'm rather new to sql, so I am not sure if it makes much of a difference (for this question) if I add that I'm using postgresql.
Note:
There is a similar question here, but it didn't have an answer that was helpful
I suggest to encapsulate the big query in a function, where you can use parameter names.
One example (out of many):
PostgreSQL parameterized Order By / Limit in table function
You can even set default values and call the function with named parameters, etc.:
Functions with variable number of input parameters

Stored procedure using NVL() on input parameter - why?

Recently, I have come to analyze a procedure in which they have used below scenario.
I want to know what is the usefulness of this ?
A procedure (cwrkid, date)
select statement
WHERE CWRK.cwrkid = NVL(in_cwrk_id,CWRK.cwrkid)
and in_cwrk_id is passed null. SO obviously, CWRK.cwrkid = CWRK.cwrkid
will always match... What the point in using variables and passing null, and ultimately satisfying a truth condition.
Am I mising something or am I thinking a lot.. :P
This is useful if you want to make the procedure reusable in future development. For now the only usecase is to select all records, but if you ever need to get only one record with a given ID you can also use this procedure.
The point is that the caller can decide whether a filter on cwrkid should be applied. One call to that function may pass NULL for that parameter, to not apply any filter. Another call to that function may pass some value for that parameter, if that caller does want to apply a filter.
I say that no filter gets applied, but I am assuming that the column is not nullable. If the column is nullable, then nulls will be filtered out, regardless of what gets passed in as the parameter value.
Normally, code like this is used to have a default behaviour in case the parameter is NULL. In this case, the WHERE-condition normally restricts to records with the given cwrkid. However, if cwrkid is null, there is no restriction.
Without the NVL, the WHERE-condition would not match at all.
Why this was done in this case is impossible to know without knowing more about the procedure and its purpose.

Possible to spy/mock Sql Server User Defined Functions?

Is it possible to mock/spy functions with T-SQL? I couldn't find anything mentioning it. I was thinking of creating my own implementation using the SpyProcedure as a guideline (if no implementation exists). Anyone had any success with this?
Thanks.
In SQL Server functions cannot have side-effects. That means, in your test you can replace the inner function with on that returns a fixed result, but there is no way to record the parameters that were past into the function.
There is one exception: If the function returns a string and the string does not have to follow a specific format, you could concatenate the passed-in parameters and then assert later on that the value coming back out contained all the correct values, but that is a very special case and not generally possible.
To fake a function, just drop or rename the original and create your own within the test. I would put this code into a helper function, as it probably will be called from more than one test.

How to pass an entire row (in SQL, not PL/SQL) to a stored function?

I am having the following (pretty simple) problem. I would like to write an (Oracle) SQL query, roughly like the following:
SELECT count(*), MyFunc(MyTable.*)
FROM MyTable
GROUP BY MyFunc(MyTable.*)
Within PL/SQL, one can use a RECORD type (and/or %ROWTYPE), but to my knowledge, these tools are not available within SQL. The function expects the complete row, however. What can I do to pass the entire row to the stored function?
Thanks!
Don't think you can.
Either create the function with all the arguments you need, or pass the id of the row and do a SELECT within the function.