将多行Table值函数转换为SQL内联(converting multiline Table valued function to inline in SQL)
考虑到性能问题,我想制作我的
multiline
表值函数,一个inline
TVF。以下是
Multiline TVF
的示例代码:CREATE FUNCTION MatchAptNumber (@AptNumberFromUser nvarchar(20)) RETURNS @MatchedData Table ( RowNumber int null , PercentMatch int null ) AS Begin Insert into @MatchedData(RowNumber) select dbo.Patients.Rowid from dbo.Patients where dbo.Patients.Aptnumber = @AptNumberFromUser update @MatchedData set PercentMatch= 100 RETURN; END; Go
这是我如何使用它:
select @constVal = FunctionWeight from dbo.FunctionWeights where FunctionWeights.FunctionName = 'MatchAptNumber'; INSERT INTO #Temp2(RowNumber, ValFromFunc, FuncWeight, percentage) SELECT RowNumber, PercentMatch, @constVal, PercentMatch * @constVal from dbo.MatchAptNumber(@Aptnumber);
是否有可能将其转换为内联TVF并按上述方式使用它? 我确实知道两者之间的语法差异但不确定如何以同样的方式使用它? 我可以得到一些指示吗?
Considering the performance issues, I wanted to make my
multiline
Table valued function, aninline
TVF.Here is the sample code for
Multiline TVF
:CREATE FUNCTION MatchAptNumber (@AptNumberFromUser nvarchar(20)) RETURNS @MatchedData Table ( RowNumber int null , PercentMatch int null ) AS Begin Insert into @MatchedData(RowNumber) select dbo.Patients.Rowid from dbo.Patients where dbo.Patients.Aptnumber = @AptNumberFromUser update @MatchedData set PercentMatch= 100 RETURN; END; Go
Here is how I use it:
select @constVal = FunctionWeight from dbo.FunctionWeights where FunctionWeights.FunctionName = 'MatchAptNumber'; INSERT INTO #Temp2(RowNumber, ValFromFunc, FuncWeight, percentage) SELECT RowNumber, PercentMatch, @constVal, PercentMatch * @constVal from dbo.MatchAptNumber(@Aptnumber);
Is it possible to convert it into an inline TVF and use it as mentioned above? I do know the syntactic differences between two but not sure how it be possible to use it the same way? Can I get some pointers on same?
原文:https://stackoverflow.com/questions/28190853
最满意答案
作为Refactor答案的附录,我认为他的方法是正确的。 他将问题细分,直到可以使用内置函数轻松解决问题。 如果你想为学习目的推出你自己的解决方案,我建议你保留这个细分,并从那里开始,实现你自己的复制。 否则,你最终会得到一个功能太多的单一功能。
所以剩下的问题就是实施复制。 我的第一个想法是查看复制的源代码 。 我通过hoogle找到了它,这引起了我的黑客行为 ,它与源代码有关。 摘录自:
replicate :: Int -> a -> [a] replicate n x = take n (repeat x)
这是很好和简洁,再次使用内置的功能。 如果你想完全推出自己的复制品,你可以这样做:
myReplicate :: Int -> a -> [a] myReplicate n x | n <= 0 = [] | otherwise = x : replicate (n-1) x
- - - - - 编辑 - - - - - - - -
作为一个便笺,我认为你的问题需要两个相当正交的技能。 首先是尽量不要立即解决整个问题,而是要取得一些小进展。 然后,您可以尝试解决这个较小的问题,然后再回到较大的问题。 就你而言,它可能会涉及到认识到你肯定需要一种将角色转换为长度为n的一系列字符的方法。 像map,filter,foldr等函数的经验会帮助你,因为它们每个都代表着一个非常独特的变换,你可能会认识到这一点。
您的解决方案所需的第二项技能 - 如果您想要自己推出 - 正在识别函数何时可以递归表示。 正如你所看到的,你的问题 - 甚至许多常见的问题 - 可以在没有明确的递归的情况下被解决,但是当需要出现时,它是一个很好的技巧。 递归解决方案并不总是很容易理解,所以我认为熟悉它们的最好方法是阅读和练习。
为了进一步研究,我相信你已经指出了优秀的学习你一个Haskell和真实世界的Haskell ,但是,如果你没有,在这里他们是。
As an addendum to Refactor's answer, I think his approach is the correct one. He subdivides the problem until it can be solved trivially using built-in functions. If you want to roll your own solution for learning purposes, I suggest you keep this subdivision, and go from there, implementing your own replicate. Otherwise, you will end up with a single function which does too much.
So the remaining problem is that of implementing replicate. My first idea would be to look at the source code for replicate. I found it via hoogle, which led me to hackage, which has links to the source code. Excerpted from the source:
replicate :: Int -> a -> [a] replicate n x = take n (repeat x)
which is nice and concise, again using the built-in functions. If you want to completely roll your own replicate, you can do:
myReplicate :: Int -> a -> [a] myReplicate n x | n <= 0 = [] | otherwise = x : replicate (n-1) x
----------EDIT----------------
As a side note, I think your problem requires two rather orthogonal skills. The first is trying not to tackle the whole problem at once, but making some small progress instead. Then you can try to solve that smaller problem, before returning to the larger. In your case, it would likely involve recognizing that you definitely need a way of transforming the character into a series of characters of length n. Experience with functions such as map, filter, foldr and so on will help you here, since they each represent a very distinct transformation, which you might recognize.
The second skill required for your solution - if you want to roll your own - is recognizing when a function can be expressed recursively. As you can see, your problem - and indeed many common problems - can be solved without explicit recursion, but it is a nice skill to have, when the need arises. Recursive solutions do not always come easily mind, so I think the best way to gain familiarity with them are to read and practice.
For further study, I'm sure you have already been pointed to the excellent Learn You a Haskell and Real World Haskell, but just in case you haven't, here they are.
相关问答
更多-
Haskell使用惰性评估来实现递归,所以将任何东西作为承诺,在需要时提供一个值(这被称为thunk)。 Thunk只有在必要的时候减少才能继续下去。 这类似于你在数学上简化表达的方式,所以有必要这样思考一下。 评估顺序没有被你的代码指定,这样一来,编译器就可以做出大量甚至更清晰的优化,而不仅仅是你惯用的尾随调用。 编译-O2如果要优化! 我们来看看我们如何评估facSlow 5作为案例研究: facSlow 5 5 * facSlow 4 -- Note that the `5-1` ...
-
如果我们将其分解,这不是一个难以解决的问题。 首先,我们需要一个函数,它接受元组列表和一个键,并返回该键存在于列表中的值。 幸运的是,已经为我们定义了查找 它返回一个Maybe值。 如果我们找不到它,那么我们不需要替换它,所以我们可以简单地返回原始值。 fromMaybe为我们做了这个,它需要一个默认值和一个可能的值,如果可能的值是一个Just,它返回just中的值。 现在我们只需要在列表上进行映射,对于每个项目,将其替换为关联列表中的项目(如果存在),如果不存在,则将其替换为自身。 这是代码: impor ...
-
作为Refactor答案的附录,我认为他的方法是正确的。 他将问题细分,直到可以使用内置函数轻松解决问题。 如果你想为学习目的推出你自己的解决方案,我建议你保留这个细分,并从那里开始,实现你自己的复制。 否则,你最终会得到一个功能太多的单一功能。 所以剩下的问题就是实施复制。 我的第一个想法是查看复制的源代码 。 我通过hoogle找到了它,这引起了我的黑客行为 ,它与源代码有关。 摘录自: replicate :: Int -> a -> [a] replicate n x ...
-
您的代码的基本问题不是它是递归的,而是它不会终止。 fact的n论证不断变得越来越大,因为[| $n - 1 ]| [| $n - 1 ]| 是表示应用于n和1的操作(-)的表达式树。 任何非终止拼接都会以相同的方式挂起编译器,例如以下行为就像拼接时的fact一样: broken :: ExpQ -> ExpQ broken n = return $ LitE (IntegerL (fromIntegral (length [1..]))) 保证递归递归的递归函数保证终止并适用于适当的输入: fact1 ...
-
添加终止条件的另一种方法是使用一个保护(这也解决了Corbin提到的<= 2条件: countStairs n | n > 0 = countStairs(n-1) + countStairs(n-2) + countStairs(n-3) | otherwise = 1 更新 您更新的Haskell示例不起作用,因为您误解了模式匹配的工作原理。 你期望它像一个守卫一样工作(当你试图在模式匹配中提供一个布尔表达式< 0时),但是,你的函数版本永远不会匹配(当你调用countSt ...
-
基本的Haskell递归函数(Basic Haskell Recursive Function)[2021-12-15]
好的 - 你不知何故必须带着你的标志 ,所以显而易见的解决方案是用一个参数来做(然后添加一个版本来修复第一个调用的这个参数): alternateSum' :: Num a => a -> [a] -> a alternateSum' _ [] = 0 alternateSum' f (h:tl) = f * h + alternateSum' (-f) tl alternateSum :: [Integer] -> Integer alternateSum ns = alternateSum' ... -
在Haskell中递归lambda(Recursive lambda in Haskell)[2022-05-16]
factorial的f是(\tn -> if n == 1 ...) lambda y是一个所谓的定点组合器 ,它用于在lambda演算中启用递归定义(它递归地将f应用于它的参数) 要了解它的工作原理,您可以手动进行一些评估 : factorial 3 = y (\t n -> ...) 3 { def y and y (\t n -> ...) = factorial by eta-red. } = (\t n -> ...) factorial 3 { t = factorial, n = 3 -> e ... -
Haskell中的递归排列(Recursive permutations in Haskell)[2022-05-04]
你的循环不一样。 i <- [len,len-1..0] VS for i in xrange(len(A)-1,-1,-1): 第一种情况,你是i的长度,而不是长度减一。 结果是delete i xs返回xs ,因此您获得无限递归。 我也有几个旁注。 首先!! 是线性时间。 你写一个结合了这个的辅助函数会好得多!! , delete和迭代输入到一个列表遍历。 类似于select :: [a] -> [(a, [a])] 。 你可以有效地做到这一点。 其次, ++也是线性时间。 使用它将单个元素附加到现 ... -
situation是功能game一个参数。 它会有类型([Move], Towers) 。 基本上,你所说的是“如果situation没有移动,那么返回塔,否则执行移动,然后将结果传递给game ”。 将此函数编写为完全合法 game ([], towers) = towers game (moves, towers) = game (move (moves, towers)) 但是这需要拆分一个元组然后构造一个与它完全相同的新元组,或者你可以使用任何其他名称来表示这个值: game ([], tower ...
-
seekMaxMin返回最小值和最大值的元组,但是在你的最后一个等式中,你首先假装它只返回最大值,其次它只返回最小值。 您可以使用模式将它们两者都提取出来,并从列表中删除冗余步骤。 seekMaxMin (x:rest) = (max x rmax, min x rmin) where (rmax, rmin) = seekMaxMin(rest) 我也有点反对将空的双打列表的min设为0,但也许它适合你使用这个函数的任何目的。 seekMaxMin returns a tuple of both ...