如何创建一个从表中返回字符串的函数SQL?

时间:2017-08-19 13:10:57

标签: sql function sql-server-2008-r2

如何创建这样的函数?

function FN_something (@entrada char(50))

declare @consulta table
declare @notificacao varchar(50)
declare @multa float
declare @saida varchar(50)

set @consulta as = (select num_notificacao,num_multa from table where field = @entrada)
set @notificacao = @consulta.num_notificacao
set @multa = @consulta.num_multa
set @saida = "resultado: "+ @notificacao +";"+@multa

return @saida

提前致谢

2 个答案:

答案 0 :(得分:0)

以下是具有正确SQL Server语法的函数示例:

create function FN_something (
    @entrada char(50)  -- should probably be `varchar(50)` rather than `char(50)`
) returns varchar(50)
begin
    declare @saida varchar(50);

    select @saida = 'resultado: ' + num_notificacao + ';' + num_multa
    from table
    where field = @entrada;

    return @saida;
end;

注意:这假定num_列是字符串,而不是数字。如果它们是数字,则需要转换它们或使用concat()

编辑:

功能真的不适合这个。可能最好的解决方案是计算列:

alter table t add something as (concat('resultado: ', num_notificacao, ';', num_multa);

然后您可以直接从表中获取值。在早期版本的SQL Server中,您将使用视图而不是计算列。

答案 1 :(得分:0)

我不会使用函数...标量函数往往是一个真正的性能杀手。尝试使用类似内嵌

的内容
SELECT 'resultado: ' 
      + ISNULL(CAST(t.num_notificacao AS VARCHAR(MAX)),'???') 
      + ';' 
      + ISNULL(CAST(t.num_multa AS VARCHAR(MAX)),'???')
FROM SomeTable AS t WHERE t.SomeField=@entrada;

如果您需要某个功能,最好使用内联 TVF(不带BEGIN...END的语法,并使用CROSS APPLY将其绑定到您的查询中。

可能会简化:

如果您的列为NOT NULL,则可以不使用ISNULL() - 函数。如果您的列是字符串,则可以不使用CAST() ...我的代码是防御性项目:-D

提示

如果这是您经常需要的内容,您可能会引入一个带有此计算列的VIEW并使用它代替您的表格。您可以将此值作为计算列包含在表中...

更新

很好,您在评论中显示的 VIEW 实际上是内嵌TVF ,这非常好!

我的神奇晶球告诉我,你可能需要这样的东西:

SELECT cl.*
      ,'resultado: ' + t.num_notificacao + ';' + t.num_multa AS CalculatedResult
FROM dbo.[CampoLivre876]('SomeParameter') AS cl
LEFT JOIN SomeOtherTable AS t ON cl.entrada=t.SomeField --should be only one related row per main row! 

这将调用iTFV并将其加入到另一个表中,其中两列是活的。我假设CampoLivre876 - 行知道它的entrada密钥。

提示2:

如果这对您有用,您可以将此方法直接包含在现有的iTVF中。

更新2

您可能会尝试像这里更改您的功能:

ALTER FUNCTION [dbo].[CampoLivre876] () 
RETURNS TABLE
RETURN 
Select cl.mul_numero_notificacao + ';' + CAST(cl.mul_valor_multa as varchar(max)) AS ExistingColumn
      ,'resultado: ' + t.num_notificacao + ';' + CAST(t.num_multa AS varchar(max)) AS CalculatedResult
From Campo_Livre AS cl With(NoLock)
INNER JOIN SomeOtherTable AS t ON cl.entrada=t.SomeField;

这应该一次读取所有行。在另一个之后阅读1行 - 几乎在所有情况下 - 真的,非常糟糕......