Only functions and extended stored procedures can be executed from within a function

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • paulnamroud
    New Member
    • Sep 2006
    • 15

    Only functions and extended stored procedures can be executed from within a function

    Hi everybody,

    When i try to excute a function i got the following error message:
    " Only functions and extended stored procedures can be executed from within a function."

    I wrote the following stored procedure wich update the sequence id :
    --------------------------------------------------------------------
    CREATE PROCEDURE dbo.pr_get_id_s equence
    (@p_nom_sequenc e varchar(100),
    @p_nom_table varchar(100),
    @p_id_sequence numeric OUTPUT ) AS

    -- return an error if sequence does not exist
    -- so we will know if someone truncates the table
    DECLARE @v_id_sequence numeric

    SET @v_id_sequence = -1

    UPDATE GST_SEQUENCE
    SET @v_id_sequence = ID_SEQUENCE = ID_SEQUENCE + 1
    WHERE NOM_SEQUENCE = @p_nom_sequence
    AND NOM_TABLE = @p_nom_table

    SET @p_id_sequence = @v_id_sequence
    RETURN @p_id_sequence


    Then, i wrote the following function which return the last value of sequence id:
    -----------------------------------------------------------------
    CREATE FUNCTION dbo.fu_get_id_s equence
    (@p_nom_sequenc e varchar(100),
    @p_nom_table varchar(100)
    ) returns int AS

    BEGIN
    DECLARE @v_id_sequence numeric

    Execute dbo.pr_get_id_s equence @p_nom_sequence , @p_nom_table, @v_id_sequence


    RETURN @v_id_sequence

    END

    And, when i try to call the function, i got the error message:
    --------------------------------------------------------------
    select dbo.fu_get_id_s equence ('SEQ', 'TABLE')


    By the way i'm using SQL Server 2005. Also, I tried to create the function by incliding the UPDATE statement but it didn't work.

    Can anyone help me ?
    Thank you

    Paul
  • almaz
    Recognized Expert New Member
    • Dec 2006
    • 168

    #2
    The error messages clearly point to the source of error: you cannot call stored procedures, as well as perform updates, deletes and inserts in T-SQL functions. That's why you cannot execute your function. You'll have to create stored procedure instead of function to be able to call another stored procedure. Also, all output parameters should be explicitly marked as output when you call a stored procedure:

    Execute dbo.pr_get_id_s equence @p_nom_sequence , @p_nom_table, @v_id_sequence output

    Comment

    • jmvspam
      New Member
      • Jul 2009
      • 1

      #3
      This UDF will help you

      Hello everybody,

      I recently had a similar issue. In fact the error message is not properly formatted since sp_executesql is an extended stored procedure as you can check by the following script:
      select objectproperty( object_id('sp_e xecutesql'),'Is ExtendedProc')
      returns
      1
      Since we can’t use sp_executesql even it’s a XP, I had to found another workaround by using sp_OAMethod: My scenario was: how to find dynamically the number of rows in a table according some criteria (null values in my scenario). Using sp_OAMethod I built the following function:

      --------------------------------
      IF object_id(N'dbo .fc_ContaRegist ros_x_Criterio' ) is not null DROP FUNCTION [dbo].[fc_ContaRegistr os_x_Criterio]
      GO
      SET QUOTED_IDENTIFI ER ON
      GO
      SET ANSI_NULLS ON
      GO
      CREATE FUNCTION dbo.fc_ContaReg istros_x_Criter io (
      @str_TBName VARCHAR(100),
      @str_Criter VARCHAR(500))
      RETURNS BIGINT
      AS
      BEGIN
      -- Objetivo : Contar numero de registros de uma determinada tabela de acordo com o critério passado
      -- Criação : Josué Monteiro Viana - 09/07/09
      /*
      Exemplo:
      DECLARE @count INT
      SET @count = dbo.fc_ContaReg istros_x_Criter io('master.dbo. sysobjects', '')
      PRINT @count
      SET @count = dbo.fc_ContaReg istros_x_Criter io('crk.dbo.aca o', 'where cod_acao is null')
      PRINT @count
      */
      DECLARE
      @int_objSQL INT,
      @int_erros INT,
      @int_objSelectC ountResult INT,
      @bint_SelectCou nt BIGINT,
      @sql NVARCHAR(2000)

      EXEC @int_erros = sp_OACreate 'SQLDMO.SQLServ er', @int_objSQL OUTPUT
      EXEC @int_erros = sp_OASetPropert y @int_objSQL, 'LoginSecure', TRUE
      EXEC @int_erros = sp_OAMethod @int_objSQL, 'Connect', null, '.'
      --SET @sql = 'SELECT count(*) FROM ' + @str_TBName + ' WHERE ' + @str_Criter
      SET @sql = 'SELECT count(*) FROM ' + @str_TBName + ' ' + @str_Criter
      SET @sql = 'ExecuteWithRes ults("' + @sql + '")'
      EXEC @int_erros = sp_OAMethod @int_objSQL, @sql, @int_objSelectC ountResult OUTPUT
      EXEC @int_erros = sp_OAMethod @int_objSelectC ountResult, 'GetRangeString (1, 1)', @bint_SelectCou nt OUT
      EXEC @int_erros = sp_OADestroy @int_objSQL
      -- debug info: not valid inside a fc
      --if @int_erros <> 0 EXEC sp_OAGetErrorIn fo @int_objSQL else print 'ok'
      if @int_erros <> 0 SET @bint_SelectCou nt = @int_erros
      RETURN @bint_SelectCou nt
      END
      GO
      SET QUOTED_IDENTIFI ER OFF
      GO
      SET ANSI_NULLS ON
      GO
      --------------------------------

      I know your case is a little different, but I’m sure you can use this udf as a guideline to help you.

      Best wishes,
      Josue Monteiro Viana

      Comment

      Working...