Cómo escribir una consulta SQL dinámica, basada en el valor de la tabla

I am trying to write a lookup/update query based on a field in one of my tables called [Tariff Lookup]. [Tariff Lookup] has already been populated based on a previous query. For example:

If [Customer Lookup] = RFT001, then lookup from Tariff A

If [Customer Lookup] = DEF001, then lookup from Tariff B

Using the below code I have managed to the get the dynamic table name value bit working, by storing the result of my SQL as a parameter called @tablevalue and then using dynamic SQL. But the trouble is that @tablevalue is a static variable, always returning “Tariff A”, where as it needs to work row by row.

DECLARE @tablevalue nvarchar(max);
DECLARE @sql nvarchar(max);

SELECT @tablevalue  = [Tariff Lookup]
FROM [DaisyBilling].[dbo].[APRW14_FFA68878_Calls];

SELECT @sql = N'UPDATE [APRW14_FFA68878_Calls] 
SET    [APRW14_FFA68878_Calls].[Sell Price] = [test].[dbo].' + @tablevalue +'.[Peak]/60*[APRW14_FFA68878_Calls].[Duration (secs)]
FROM   [Test].[dbo]. ' + @tablevalue +'
INNER JOIN [DaisyBilling].[dbo].[APRW14_FFA68878_Calls] on [DaisyBilling].[dbo].[APRW14_FFA68878_Calls].[ChargeCode] = [Test].[dbo]. ' + @tablevalue +'.[Chargecode]';

EXEC sp_executesql @sql

Estructuras de mesa

APRW14_FFA68878_Calls

Tariff Table

What I need to do is to populate the [Sell Price] value on the [APRW14_FFA68878_Calls] table. Which is a calucation of the [Peak] value from the Tariff table. So for example .[Peak]/60*[APRW14_FFA68878_Calls].[Duration (secs)]

Somebody has previously mentioned that using SQL cursors might be the way forward, but I am not sure how to format a Cursor query.

Also this is part of a VB.net project, so I am not sure if it will be best to use VB or SQL.

Any pointers or advice greatly appreciated.

PS. I am relatively new to VB/SQL, so if anyone can provide code examples that will also help.

Muchas Gracias

UPDATE: I am now using the Cursor method as suggested below, but it loops 6376 times, each time updating 6376 records. How can I make it so it updates each single row 1 time? Thanks

preguntado el 28 de mayo de 14 a las 14:05

Can you also add an output/Desired result set? you have explained what you have done so far very well. but yet you havent really explained much what would you like to have. -

SELECT @tablevalue = [Tariff Lookup] FROM [DaisyBilling].[dbo].[APRW14_FFA68878_Calls]; Wont this code result in error when there are more than one record in the table? -

@M.Ali - I am trying to populate the [Sell Price] value on the [APRW14_FFA68878_Calls] table. Which is a calucation of the [Peak] value in the Tariff table. So for example .[Peak]/60*[APRW14_FFA68878_Calls].[Duration (secs)] -

@ Jithin Shaji - I have more than one record in the table and no it doesn't error - But I know that part of the code is wrong and that is what I am trying to get help with. -

Stop putting your Tariff information in different tables. Put it all in one table and distinguish the rows by a Tariff_Name or Tariff_ID. Otherwise you will be continuously be faced with this problem with only horrible, kludgy solutions. -

2 Respuestas

You can set up the cursor like this:

DECLARE @tablevalue NVARCHAR(MAX)
        , @sql NVARCHAR(MAX);


DECLARE table_value_cursor CURSOR FOR
SELECT  [Tariff Lookup] 
FROM    [DaisyBilling].[dbo].[APRW14_FFA68878_Calls];

OPEN table_value_cursor 
FETCH NEXT FROM table_value_cursor INTO @tablevalue

WHILE @@FETCH_STATUS = 0   
BEGIN   
    SELECT @sql = N'UPDATE [APRW14_FFA68878_Calls] 
    SET    [APRW14_FFA68878_Calls].[Sell Price] = [test].[dbo].' + @tablevalue +'.[Peak]/60*[APRW14_FFA68878_Calls].[Duration (secs)]
    FROM   [Test].[dbo]. ' + @tablevalue +'
    INNER JOIN [DaisyBilling].[dbo].[APRW14_FFA68878_Calls] on [DaisyBilling].[dbo].[APRW14_FFA68878_Calls].[ChargeCode] = [Test].[dbo]. ' + @tablevalue +'.[Chargecode]';

    EXEC sp_executesql @sql;
    FETCH NEXT FROM table_value_cursor INTO @tablevalue;
END   

CLOSE table_value_cursor   
DEALLOCATE table_value_cursor;

contestado el 28 de mayo de 14 a las 15:05

Thanks @ Kevin Suchlicki - I am not in front of my project at the moment, but will try this later today. - user3580480

Ok, so it is cycling through the loop now, but takes ages and displays (6376 row(s) affected), 6376 times - How can I code it so that it does 1 change per row. Thanks - user3580480

I dont know what you are doing with all these variables and Dynamic Sql I would have wrote this query simply something like this....

UPDATE T 
SET    T.[Sell Price] = (TL.[Peak] / 60) * T.[Duration]
FROM       [DaisyBilling].[dbo].[APRW14_FFA68878_Calls] T 
INNER JOIN [test].[dbo].[Tarrif] TL
ON T.[ChargeCode] = TL.[Chargecode]

contestado el 28 de mayo de 14 a las 15:05

+1: a better answer. Unfortunately, the likely answer to your question is that the OP does not have a relational design but rather has separate tables for every Tariff. They would be well advised to change their design so that they could just use SQL code like yours, above. - rbarryjoven

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.