0

Can I define a custom, user-defined function that will stay active for as long as the sqlsrv_connect connection stays on? If it can't stay on for the whole connection time, I could live with it being defined at least just before the execution of a specific SELECT query.

Specifically, for a particular SELECT query I want to use something like the UPPER function, which will drop accents of Greek capital letters... So I crafted my custom function that will take care of that, named it UPPERGR but I don't know how to execute this query...

CREATE FUNCTION UPPERGR(@Word nvarchar(max))
    RETURNS nvarchar(max)
    AS
    BEGIN
        DECLARE @Ret nvarchar(max);
        SET @Ret = UPPER(@Word);
        SET @Ret = REPLACE(@Ret,'Ά','Α');
        SET @Ret = REPLACE(@Ret,'Έ','Ε');
        SET @Ret = REPLACE(@Ret,'Ή','Η');
        SET @Ret = REPLACE(@Ret,'Ί','Ι');
        SET @Ret = REPLACE(@Ret,'Ό','Ο');
        SET @Ret = REPLACE(@Ret,'Ύ','Υ');
        SET @Ret = REPLACE(@Ret,'Ώ','Ω');
        RETURN @Ret;
    END;

So I want to run the command above just before executing my SELECT query below:

SELECT prod.ID,
                   prod.CODE,
                   prod.DESCRIPTION AS TITLE,
                   prod.REMARKS AS DESCRIPTION,
                   prod.DESCR2 AS SHORTDESCRIPTION,
                   manuf.DESCR AS MANUFACTURER,
                   CONCAT(UPPERGR(cat1.DESCR), ' > ', UPPERGR(cat2.DESCR), ' > ', UPPERGR(cat3.DESCR)) AS CATEGORIES,
                   ...

Can someone help me with this unusual task please? Thank you in advance!

Faye D.
  • 833
  • 1
  • 3
  • 16
  • 2
    A function exists until dropped, its not connection dependent. And the [official documentation](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql?view=sql-server-ver15) shows how to call it. – Dale K Sep 28 '21 at 01:09
  • @DaleK can you please point me to that resource? I've searched but couldn't find that! Obviously I didn't use the correct keywords for it to be returned to me... – Faye D. Sep 28 '21 at 01:12
  • Ah yes, sorry it's already 4:14am in my time-zone! I'll have a look at the resource, and hopefully I'll figure it out! Thanks a lot! :D – Faye D. Sep 28 '21 at 01:15
  • @DaleK the resource you posted describes how to write the SQL command to `CREATE FUNCTION`! That's not my problem, I've created that as you can see. The problem is I can't run it. I mean, I've already tried the `sqlsrv_query($connection, $sql);` that runs such a query in PHP, but when I then run my other `SELECT` query, I get that `UPPERGR` is not defined! – Faye D. Sep 28 '21 at 01:22
  • The examples at the bottom show how to call it. – Dale K Sep 28 '21 at 01:23
  • 2
    `Scalar functions must be invoked by using at least the two-part name of the function (.).` - maybe you didn't see this? – Dale K Sep 28 '21 at 01:25
  • You're going to run into issues creating the function every time you use it unless you check whether it already exists. – Dale K Sep 28 '21 at 01:30
  • Yeah, that's what I just found out! Once I used the part in calling the function, like you suggested, I got the error `[message] => [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]There is already an object named 'UPPERGR' in the database.` I'm fixing that also! Coming from MySQL, SQL Server realm is so new to me... But I took up the project, so here I am... – Faye D. Sep 28 '21 at 01:41
  • 1
    Consider using national literals like `N'Ώ'` so that you're not subject to the database's default collations causing loss of characters. That code seems like it could be a one-liner using [TRANSLATE (Transact-SQL)](https://learn.microsoft.com/en-us/sql/t-sql/functions/translate-transact-sql) as well. – AlwaysLearning Sep 28 '21 at 01:42
  • @AlwaysLearning TRANSLATE, from what I see, is for SQL Server 2017+ while the project is using 2014 though... Other than that, I quite didn't understand the national literals like `N'Ώ'` that you mentioned. Could you give me an example please? – Faye D. Sep 28 '21 at 02:41
  • You're dealing with Unicode characters and putting them into regular string literals. Depending on your default database collation `select 'Ά','Α','Έ','Ε','Ή','Η','Ί','Ι','Ό','Ο','Ύ','Υ','Ώ','Ω'` is likely to return `? ? ? ? ? ? ? ? ? ? ? ? ? O` whereas `select N'Ά',N'Α',N'Έ',N'Ε',N'Ή',N'Η',N'Ί',N'Ι',N'Ό',N'Ο',N'Ύ',N'Υ',N'Ώ',N'Ω'` returns the expected characters `Ά Α Έ Ε Ή Η Ί Ι Ό Ο Ύ Υ Ώ Ω`. – AlwaysLearning Sep 28 '21 at 03:06
  • Ah OK, now I get you! That's not a problem however, the DB collation is the proper one! – Faye D. Sep 28 '21 at 03:19
  • `You're going to run into issues creating the function every time you use it unless you check whether it already exists.`: I am sure that you remember @DaleK that You are not obligated to check if the function exists if you are using SQL Server 2019, since SQL Server supports "CREATE OR ALTER" for functions `:-)` – Ronen Ariely Sep 28 '21 at 13:42
  • I hate that we cannot add code in the comment and have technical discussion. I uploaded image with example of using `CREATE OR ALTER FUNCTION` https://i.stack.imgur.com/BdBEq.png – Ronen Ariely Sep 28 '21 at 13:51
  • Since this discussion still draws attention, let me update you people on what I ended up doing! So, at first I coded it like this: `sqlsrv_query($connection, "IF OBJECT_ID('altec.UPPERGR') IS NOT NULL DROP FUNCTION altec.UPPERGR; CREATE FUNCTION altec.UPPERGR(@Word nvarchar(max)) RETURNS nvarchar(max) AS ...` but then I got an error saying that `CREATE FUNCTION` must be the first one in a batch of commands... So I ended up doing it the opposite way... At the beginning of the PHP script I'm `CREATE`ing it, and at the end of it I'm `DROP`ing it! – Faye D. Sep 28 '21 at 18:51
  • @FayeD. why not leave the function in the database permanently? Its a very strange pattern to create it every time you need it. – Dale K Sep 28 '21 at 19:16
  • @DaleK of course I wouldn't have a problem to keep the function in the DB, but even in these two replies https://stackoverflow.com/a/8886887/15576971 https://stackoverflow.com/a/8886872/15576971, they suggest the same thing: 1. Check if exists 2. If yes, drop it 3. Create it all over again... That, together with the fact that in my case, I was getting the error that `CREATE FUNCTION` would need to be the first in the batch, made me decide that I should flip the order to 1. Create 2. (Of course use) 3. Check if exists (typical), then drop... And so far it works very well... – Faye D. Sep 29 '21 at 00:20

0 Answers0