技术开发 频道

在SQL Server2005中实现数组映射(一)



【IT168 专稿】


    SQL
语言一直以来被认为在最近三十年中是发展最慢的语言之一。但SQL却可以在专家手中得心应手,发挥出更大的作用。而有很多专家认为,把SQL和其他的语言相比是完全没有必要的。虽然SQL没有现在语言中的局部变量,语言结构、以及缺少一些基本的功能。然而,我们却可以使用存储过程来扩展这种语言。在本文中将描述如何使用存储过程来增强SQL语言的力量,这其中包括增加数组功能、矩阵以及列表处理任务等。例如,我们可以做到如下的事情:

1. 
在一个结果集中列中任意多个表中每个表的行数。
2.  使用一个INSERT表达式模板来为每个表执行这个INSERT表达式。
3.  使用不同的字段将一组表连接起来,并显示它们的行数。即使字段的名子不同。
4.  可以为不同组的用户分配不同的权限。或是为每个用户分配所有的权限。

   
上面所显示的对于任何SQL库来说都是强大的功能,有了这些功能,我们可以用几分钟完成以前需要几小时才能做完的工作。
   
首先、我们需要了解一些关于数学映射方法的概念。在PerlC#中这些映射是很常见的,由于在这些语言中的这些功能和SQL有机地结合,才使SQL可以发挥出更强大的功能。在本文中,我们将看到一些使用SP_map存储过程的例子。这些功能不仅仅是例子,它们完全可以当作程序中的关键特性被使用。最后,我们将学习如何在本机上安装这些存储过程。

一、映射概述

   
映射特性在大多数的功能型编程语言中都可以找到,这种特性一般很少在过程或命令型语言中使用。一个关键的区别是“命令型语言的目的是强调一系列执行步骤来完成每项操作,而功能型语言的目的是对逻辑和功能的安排,而一般不需要清楚地指定步骤”。 

   
 Perl是一种典型的命令型语言,但是它可以很好的被当作功能型语言来使用。在实际工作中,它提供一种非常实用的映射能力。下面是一个非常简单的例子,这个例子将一个整数列表映射成和它们等效的ASCII值,我们只使用三行就可以完成上面的功能,代码如下:

 

   @chars = map(chr, @nums); 
   @chars = map { chr } @nums; 
   @chars = map { chr($_) } @nums;



图1 基本的数组映射事例:使用Perl的chr()函数将一个输入数组映射到另一个输出数组中(两个数组相同)
    上面代码的map操作符不仅限于当作函数使用,它还可以被当作处理操作符使用,如下面的代码所示:
 
   %hash = map { getkey($_) => $_ } @array;
 
    换句话说,上面一行代码的作用是通过代码块(getkey($_)=>$_)来映射输入数组(@array),并将其保存在哈希表中(%hash)。这行代码和下面的的过程型表达形式等效。
 
   %hash = ();
   foreach $element (@array) {
       $hash{getkey($element)} = $element;
   }

    如果我们不了解Perl也没关系。从上面的代码片段中可以猜测到是通过一个循环来扫描数组,并将其逐个填入哈希表。
    在Perl中的函数映射表达式显得很复杂,如下面的代码通过一个特殊的被包含在每个记录中的字段来分类结构:

   @ordered = map { $_->[1] }
              sort { $a->[0] <=> $b->[0] }
              map { [compute(), $_] }
             @unordered;

    现在让我们看一看在C#中与之等效的例子。C#(版本为2.0或更高)提高了可以转换任何数据(ConvertAll)的泛型方法,这个方法和Perl中的map等效。一个C#2.0函数列表处理的代码如下所示:
 
   List outputList =
       list.ConvertAll(delegate(string s) { return s.ToLower(); });
 

    在上面的代码中将一个匿名的函数定义成了一个代理(delegate),并将这个匿名函数传入List对象中的映射方法(ConvertAll),然后返回一个新的List对象,这个新的对象包含了所有原List中被转换为小写字符的元素。而Perl中与之等效的是如下代码所示:
 
   @outputList = map { tr/A-Z/a-z/;$_} @list;
 
    正象Perl可以通过链锁产生复杂的转换,C#也可以。下面这个例子产生了所有比被给定尺寸大的文件列表:
 
   List paths = new List(
      Directory.GetFiles(directory));
      return paths.ConvertAll( File.OpenRead )
         .FindAll( delegate(FileStream f) { return f.Length >= bigLength; } )
         .ConvertAll( delegate(FileStream f) { return f.Name; } );
 
    上面的一些代码给出了如何在Perl和C#中使用映射,那么在本文的下面部分将介绍如何在数据库中进行映射处理。

 

0
相关文章