是否有任何方法可以使用类似下面的c#代码存储过程或函数:
我想将此方法转换为T-SQL。
public static IEnumerable<String> GetWords(Int32 length)
{
if ( length <= 0 ) yield break ;
for (Char c = '!'; c <= '~'; c++)
{
if ( length > 1 )
{
foreach ( String restWord in GetWords( length - 1 ) )
yield return c + restWord;
}
else
yield return "" + c;
}
}
答案 0 :(得分:1)
你确实意识到,不管你正在做什么实际上是在生成一系列基数为94的数字...而你所生成的字符串的域变化很大,非常快。例如,使用您的字符集(0x21-0x7E),有
因此,如果你要这样做,请创建一个SQL Server CLR table-valued function来动态生成它们。
你在构建字符串的方式很可能......在'堆'和字符串实习表中有点难。对于初学者,我会将程序集标记为不通过程序集属性CompilationRelaxationsAttribute
进行字符串实习。
并使用一种使用单个固定大小StringBuilder
的非递归方法。这是一个SQL Server表值函数,它使用该方法执行代码所做的事情:
using Microsoft.SqlServer.Server;
class MySqlServerDotNetFunctions
{
[SqlFunction( TableDefinition="id int not null , value varchar(2000)" , FillRowMethodName="FillRow")]
public static IEnumerable<Tuple<long,StringBuilder>> GenerateStrings( int stringLength )
{
const char lowerBound = '!' ;
const char upperBound = '~' ;
if ( stringLength < 1 || stringLength > 2000 ) throw new ArgumentOutOfRangeException("stringLength","string length must be in the range 1-2000" ) ;
// initialize the stringbuilder
bool carry = false ; // carry flag
StringBuilder sb = new StringBuilder(new string(lowerBound,stringLength)) ;
for ( long i = 0 ; !carry && ++i > 0 ; )
{
// return the current iteration
yield return new Tuple<long,StringBuilder>(i,sb) ;
// increment our string
int p = sb.Length-1 ; // we work right-to-left
do
{
carry = ++sb[p] > upperBound ;
if ( carry )
{
sb[p] = lowerBound ;
}
} while ( carry && --p >= 0 ) ;
}
}
public static void FillRow( object o , out long id , out string value )
{
Tuple<long,StringBuilder> item = (Tuple<long,StringBuilder>) o ;
id = item.Item1 ;
value = item.Item2.ToString() ;
return ;
}
}