记得初中时住校吃饭堂,那时候每周伙食费是20元。早上1元,午餐晚餐各1.5元(周末则回家)。
早餐一般是一碗很稀的粥,上面漂浮着一块或者两块油汪汪的肥肉,外加一个包子。星期三则是猪骨头汤米粉,——当然是没有包子了,——所以,早操一结束,大家就集体逃亡一般奔向饭堂。最开始冲过去的在每个窗口前排成两列,排到十几个之后,后面的大都是女生。其它男同学则会绕到侧面,伺机斜插进去。
曾经有个走读的同学问我,住校时排队很长吗?我认真地想了想,“排队不长,只是很粗”。她笑了,“你很幽默。”然后我也笑了,虽然我并不是一个幽默的人。直到后来学生会组织了一些学生干部专门去维持秩序,才开始“化宽为长”。
正如太宽的队伍常常有不遵守秩序的嫌疑,太宽的数据表也常常有不遵守第二范式的嫌疑。而违反它,在数据库中往往会引发很多问题,表维护不方便,难以统计分析,查询不好处理等等……所以“化宽为长”就变得很重要了。
化宽为长的前提是要求“宽”的那部分拥有共同的属性,就像宽的那部分队伍一样(都是男同学,都在队伍侧面),例如,都是数值型,都在最右边的字段等等。如果没有这些,当然谈不上化宽为长了。先看看效果吧:
代码如下,具体见示例文件。喜欢的话,就回个帖吧。
Function getSQL(ByVal strTableName As String, ByVal strEndFieldName As String) As String
Dim rst As New ADODB.Recordset
Dim i As Long
Dim lngPosition As Long
Dim strSQL As String, strSQL2 As String
Dim dic As New Dictionary
Dim lngEnd As Long
rst.Open strTableName, CurrentProject.Connection, adOpenKeyset, adLockOptimistic
'查找字段分割点的位置
For i = 0 To rst.Fields.Count - 1
If rst.Fields(i).Name = strEndFieldName Then
lngEnd = i
Exit For
End If
Next
'切割字段
For i = 0 To rst.Fields.Count - 1
'在分割点之前,直接连接字符串
If i <= lngEnd Then
strSQL = strSQL & rst.Fields(i).Name & ","
Else
'在分割点之后,写入字典,用于确定变量名和变量值。
dic.Add i, rst.Fields(i).Name
End If
Next
'关闭记录集
rst.Close
'准备语句
For i = 0 To dic.Count - 1
strSQL2 = strSQL2 & "select " & strSQL & """" & _
dic.Items(i) & """ as 变量名称,[" & _
dic.Items(i) & "] as 变量值 from " & strTableName & " union all "
Next
getSQL = Left(strSQL2, Len(strSQL2) - 11)
End Function