填充Datagrid和Sql查询 [英] Filling Datagrid And Sql Query

查看:175
本文介绍了填充Datagrid和Sql查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在下面的数据库中有3个表。而且我想像下面的链接一样做一个报告。如何使用datagrid或datalist?哪一个是最好的选择?我试图做一个星期。




COMPANY :ID_COMPANY,COMPANY_NAME



PRODUCT :ID_PRODUCT,PRODUCT_NAME



PRODUCT_SALE :ID_COMPANY,ID_PRODUCT,SALE_COUNT


已更新



我可以做它与你的帮助。然而,现在我也有一个小问题。



当我用点心编写查询时,产品的名称成为列标题。如果产品名称的长度大于30个字符,则Oracle不会将其作为列标题。所以我已经裁剪了产品名称30个字符来解决这个问题。之后,也会出现问题。



当我将产品名称裁剪为30个字符时,某些产品变为相同的名称,并出现ORA-00918:列模糊定义错误消息。



在这种情况下可以做什么?

解决方案

标准的sql查询(在性能方面,枢轴是昂贵的),并在您的服务器端代码中创建一个自定义的枢纽功能。以下是几个例子。

 '''< summary> 
'''Pivots columnX作为X轴的新列(必须是唯一值),剩余列为
'Y轴。可选地,可以包括从Y轴排除的列。
'''< / summary>
'''< param name =dt>< / param>
'''< param name =columnX>< / param>
'''< param name =columnsToIgnore>< / param>
'''< returns> DataTable< / returns>
'''< remarks>< / remarks>
公共共享函数数据透视(ByVal dt As DataTable,ByVal columnX As String,ByVal ParamArray columnsToIgnore As String())As DataTable

Dim dt2 As New DataTable()

如果columnX =然后
columnX = dt.Columns(0).ColumnName
End If

'在表的开头添加一个列
dt2.Columns.Add(columnX)

'从提供的DataTable
中的columnX列中读取所有DISTINCT值Dim columnXValues As New List(Of String)()

'创建要忽略的列列表
Dim listColumnsToIgnore As New List(Of String)()
如果columnsToIgnore.Length> 0然后
listColumnsToIgnore.AddRange(columnsToIgnore)
结束如果

如果没有listColumnsToIgnore.Contains(columnX)然后
listColumnsToIgnore.Add(columnX)
结束如果

'添加X轴列
对于每个dr As DataRow在dt.Rows
Dim columnXTemp As String = dr(columnX).ToString()
如果不是columnXValues.Contains(columnXTemp)然后
columnXValues.Add(columnXTemp)
dt2.Columns.Add(columnXTemp)
Else
抛出新异常(所用的反转必须有唯一的列+ columnX的值
结束如果
下一个

'为DataTable
的每个非columnX添加一行对于每个dc作为DataColumn在dt中。列
如果不是columnXValues.Contains(dc.ColumnName)AndAlso不是列表ColumnsToIgnore.Contains(dc.ColumnName)然后
Dim dr As DataRow = dt2.NewRow()
dr(0)= dc .ColumnName
dt2.Rows.Add(dr)
结束如果
下一个

'使用值
完成数据表对于i As Integer = 0到dt2.Rows.Count - 1
对于j As Integer = 1到dt2.Columns.Count - 1
dt2.Rows(i)(j)= dt.Rows(j - 1)(dt2.Rows(i) 0).ToString())ToString()
下一个
下一个

返回dt2

结束函数

' ''< summary>
'''可以将任何列转换为X,任何列为Y,任何列为Z.对X排序,Y上排序,可选地,x和x的交集处的
''值y(Z轴)可以相加。
'''< / summary>
'''< param name =dt>< / param>
'''< param name =columnX>< / param>
'''< param name =columnY>< / param>
'''< param name =columnZ>< / param>
'''< param name =nullValue>< / param>
'''< param name =sumValues>< / param>
'''< param name =xSort>< / param>
'''< param name =ySort>< / param>
'''< returns> DataTable< / returns>
'''< remarks>< / remarks>
公共共享函数数据透视(ByVal dt As DataTable,ByVal columnX As String,ByVal columnY As String,ByVal columnZ As String,_
ByVal nullValue As String,ByVal sumValues As Boolean,ByVal xSort As Sort,ByVal ySort As Sort)As DataTable

Dim dt2 As New DataTable()
Dim tickList As List(Of Long)= Nothing

如果columnX =Then
columnX = dt.Columns(0).ColumnName
End If

'在表的开头添加一个列
dt2.Columns.Add(columnY)

'从提供的DataTable
中的columnX列中读取所有DISTINCT值Dim columnXValues As New List(Of String)()
Dim cols As Integer = 0

对于每个dr As DataRow在dt.Rows
如果dr(columnX).ToString.Contains(')然后
dr(columnX)= dr(columnX).ToString.Replace(' ,)
End If
如果不是columnXValues.Contains(dr(columnX).ToString)Then
'读取每一行值,如果它与其他值不同,
'添加到值列表中,并创建一个带有其值的新列。
columnXValues.Add(dr(columnX).ToString)
End If
Next

'如果需要,排序X
如果不是xSort = Sort.None然后
columnXValues = SortValues(columnXValues,xSort)
End If

'添加columnX
对于每个s As String在columnXValues
dt2.Columns.Add (s)
下一个

'验证提供Y和Z轴列
如果columnY& AndAlso columnZ 然后
'读取Y轴列的DISTINCT值
Dim columnYValues作为新列表(Of String)()

对于每个dr As DataRow在dt.Rows
如果dr(columnY).ToString.Contains(')然后
dr(columnY)= dr(columnY).ToString.Replace(',)
End If
如果不是列YValues.Contains(dr(columnY).ToString())然后
columnYValues.Add(dr(columnY).ToString())
结束如果
下一个

'现在我们可以根据需要排序Y轴。
如果不是ySort = Sort.None然后
columnYValues = SortValues(columnYValues,ySort)
结束如果

'循环所有不同的列Y值
对于每个columnYValue As String在columnYValues中
'创建一个新行
Dim drReturn As DataRow = dt2.NewRow()
drReturn(0)= columnYValue
Dim rows As DataRow()= dt 。[Select](columnY +='+ columnYValue +')

'读取每一行以填充DataTable
对于每个dr As DataRow在行
Dim rowColumnTitle As String = dr(columnX).ToString()

'读取每列填充DataTable
对于每个dc作为DataColumn在dt2.Columns
如果dc.ColumnName = rowColumnTitle然后
'如果sumValues,尝试执行Sum
'如果由于值类型而无法实现总和s,使用nullValue字符串
如果sumValues然后
如果IsNumeric(dr(columnZ).ToString)然后
drReturn(rowColumnTitle)= Val(drReturn(rowColumnTitle).ToString)+ Val(dr (columnZ).ToString)
Else
drReturn(rowColumnTitle)= nullValue
End If
Else
drReturn(rowColumnTitle)= dr(columnZ).ToString
结束如果
结束如果
下一个
下一个

dt2.Rows.Add(drReturn)

下一个
Else
抛出新的异常(不提供执行反转的列)
End If

'如果提供了nullValue参数,请使用它填充datable
如果nullValue < 然后
对于每个dr作为DataRow在dt2.Rows
对于每个dc作为DataColumn在dt2.Columns
如果dr(dc.ColumnName).ToString()=然后
dr(dc.ColumnName)= nullValue
结束如果
下一个
下一个
结束如果

返回dt2

结束函数

'''< summary>
'''排序检查字符串列表以查看它们是数字类型还是日期类型。
'''< / summary>
'''< param name =list>< / param>
'''< param name =srt>< / param>
'''< returns>< / returns>
'''< remarks>< / remarks>
私有共享函数SortValues(ByVal list As List(Of String),ByVal srt As Sort)As List(Of String)

Dim tickList As List(Of Long)= Nothing
Dim dblList As List(Of Double)= Nothing

'找出如何排序columnX
对于每个s As String在列表
Dim colDate As Date = Nothing
如果Date.TryParse(s,colDate)然后
tickList =新列表(长)
退出
结束如果
下一个

Dim dateTicks As Long

如果不是tickList不是然后
对于每个s作为字符串在列表
dateTicks = DateTime.Parse(s).Ticks
如果不是tickList.Contains (dateTicks)然后
tickList.Add(dateTicks)
结束如果
下一个

如果srt = Sort.DESC然后
tickList.Sort()
tickList.Reverse()
ElseIf srt = Sort.ASC然后
tickList。 Sort()
End If

list.Clear()
对于每个lng As Long在tickList
list.Add(New Date(lng).ToString( G))
下一个
Else
Dim dbl As Double = Nothing

对于每个s As String在列表
如果IsNumeric(s)Then
dblList =新列表(双倍)
结束如果
下一个

如果不是dblList不是然后
'双重或整数
对于每个s as String在列表
dbl = Val(s)
如果不是dblList.Contains(dbl)然后
dblList.Add(dbl)
结束如果
下一个

如果srt = Sort.DESC然后
dblList.Sort()
dblList.Reverse()
ElseIf srt = Sort.ASC然后
dblList.Sort ()
End If

list.Clear()
对于每个d As Double在dblList
list.Add(d.ToString)
下一个
Else
'字符串
如果srt = Sort.DESC然后
list.Sort()
list.Reverse()
ElseIf srt = Sort.ASC然后
list.Sort()
End If
End If

如果

返回列表

结束函数


I have 3 tables in database shown below. And I want to make a report just like shown link below. How can I do it with datagrid or datalist? Which one is the best chois? I have tried to do it for a week.

COMPANY: ID_COMPANY, COMPANY_NAME

PRODUCT: ID_PRODUCT, PRODUCT_NAME

PRODUCT_SALE: ID_COMPANY, ID_PRODUCT, SALE_COUNT

Updated :

I could do it, with your helps. However Now I have a small problem too.

When I write query with pivot, products' name become column header. if a product name's length is bigger than 30 character, Oracle don't accept it as a column header. So I have croped and make the product names 30 character to solve this problem. After that a problem occured too.

When I crop product name as 30 character, some products become same name and "ORA-00918: column ambiguously defined" error message occured.

In this case what can be done?

解决方案

Use a standard sql query (pivots are expensive in terms of performance) and create a custom pivot function in your server side code. Here are a couple of examples.

''' <summary>
''' Pivots columnX as new columns for the X axis (must be unique values) and the remaining columns as 
''' the Y axis. Optionally can include columns to exclude from the Y axis.
''' </summary>
''' <param name="dt"></param>
''' <param name="columnX"></param>
''' <param name="columnsToIgnore"></param>
''' <returns>DataTable</returns>
''' <remarks></remarks>
Public Shared Function Pivot(ByVal dt As DataTable, ByVal columnX As String, ByVal ParamArray columnsToIgnore As String()) As DataTable

    Dim dt2 As New DataTable()

    If columnX = "" Then
        columnX = dt.Columns(0).ColumnName
    End If

    'Add a Column at the beginning of the table 
    dt2.Columns.Add(columnX)

    'Read all DISTINCT values from columnX Column in the provided DataTable 
    Dim columnXValues As New List(Of String)()

    'Create the list of columns to ignore 
    Dim listColumnsToIgnore As New List(Of String)()
    If columnsToIgnore.Length > 0 Then
        listColumnsToIgnore.AddRange(columnsToIgnore)
    End If

    If Not listColumnsToIgnore.Contains(columnX) Then
        listColumnsToIgnore.Add(columnX)
    End If

    ' Add the X axis columns
    For Each dr As DataRow In dt.Rows
        Dim columnXTemp As String = dr(columnX).ToString()
        If Not columnXValues.Contains(columnXTemp) Then
            columnXValues.Add(columnXTemp)
            dt2.Columns.Add(columnXTemp)
        Else
            Throw New Exception("The inversion used must have unique values for column " + columnX)
        End If
    Next

    'Add a row for each non-columnX of the DataTable 
    For Each dc As DataColumn In dt.Columns
        If Not columnXValues.Contains(dc.ColumnName) AndAlso Not listColumnsToIgnore.Contains(dc.ColumnName) Then
            Dim dr As DataRow = dt2.NewRow()
            dr(0) = dc.ColumnName
            dt2.Rows.Add(dr)
        End If
    Next

    'Complete the datatable with the values 
    For i As Integer = 0 To dt2.Rows.Count - 1
        For j As Integer = 1 To dt2.Columns.Count - 1
            dt2.Rows(i)(j) = dt.Rows(j - 1)(dt2.Rows(i)(0).ToString()).ToString()
        Next
    Next

    Return dt2

End Function

''' <summary>
''' Can pivot any column as X, any column as Y, and any column as Z. Sort on X, sort on Y and optionally, the 
''' values at the intersection of x and y (Z axis) can be summed.
''' </summary>
''' <param name="dt"></param>
''' <param name="columnX"></param>
''' <param name="columnY"></param>
''' <param name="columnZ"></param>
''' <param name="nullValue"></param>
''' <param name="sumValues"></param>
''' <param name="xSort"></param>
''' <param name="ySort"></param>
''' <returns>DataTable</returns>
''' <remarks></remarks>
Public Shared Function Pivot(ByVal dt As DataTable, ByVal columnX As String, ByVal columnY As String, ByVal columnZ As String, _
    ByVal nullValue As String, ByVal sumValues As Boolean, ByVal xSort As Sort, ByVal ySort As Sort) As DataTable

    Dim dt2 As New DataTable()
    Dim tickList As List(Of Long) = Nothing

    If columnX = "" Then
        columnX = dt.Columns(0).ColumnName
    End If

    'Add a Column at the beginning of the table 
    dt2.Columns.Add(columnY)

    'Read all DISTINCT values from columnX Column in the provided DataTable 
    Dim columnXValues As New List(Of String)()
    Dim cols As Integer = 0

    For Each dr As DataRow In dt.Rows
        If dr(columnX).ToString.Contains("'") Then
            dr(columnX) = dr(columnX).ToString.Replace("'", "")
        End If
        If Not columnXValues.Contains(dr(columnX).ToString) Then
            'Read each row value, if it's different from others provided, 
            'add to the list of values and creates a new Column with its value. 
            columnXValues.Add(dr(columnX).ToString)
        End If
    Next

    'Sort X if needed
    If Not xSort = Sort.None Then
        columnXValues = SortValues(columnXValues, xSort)
    End If

    'Add columnX
    For Each s As String In columnXValues
        dt2.Columns.Add(s)
    Next

    'Verify Y and Z Axis columns were provided 
    If columnY <> "" AndAlso columnZ <> "" Then
        'Read DISTINCT Values for Y Axis Column 
        Dim columnYValues As New List(Of String)()

        For Each dr As DataRow In dt.Rows
            If dr(columnY).ToString.Contains("'") Then
                dr(columnY) = dr(columnY).ToString.Replace("'", "")
            End If
            If Not columnYValues.Contains(dr(columnY).ToString()) Then
                columnYValues.Add(dr(columnY).ToString())
            End If
        Next

        ' Now we can sort the Y axis if needed. 
        If Not ySort = Sort.None Then
            columnYValues = SortValues(columnYValues, ySort)
        End If

        'Loop all Distinct ColumnY Values
        For Each columnYValue As String In columnYValues
            'Create a new Row 
            Dim drReturn As DataRow = dt2.NewRow()
            drReturn(0) = columnYValue
            Dim rows As DataRow() = dt.[Select](columnY + "='" + columnYValue + "'")

            'Read each row to fill the DataTable 
            For Each dr As DataRow In rows
                Dim rowColumnTitle As String = dr(columnX).ToString()

                'Read each column to fill the DataTable 
                For Each dc As DataColumn In dt2.Columns
                    If dc.ColumnName = rowColumnTitle Then
                        'If sumValues, try to perform a Sum 
                        'If sum is not possible due to value types, use the nullValue string
                        If sumValues Then
                            If IsNumeric(dr(columnZ).ToString) Then
                                drReturn(rowColumnTitle) = Val(drReturn(rowColumnTitle).ToString) + Val(dr(columnZ).ToString)
                            Else
                                drReturn(rowColumnTitle) = nullValue
                            End If
                        Else
                            drReturn(rowColumnTitle) = dr(columnZ).ToString
                        End If
                    End If
                Next
            Next

            dt2.Rows.Add(drReturn)

        Next
    Else
        Throw New Exception("The columns to perform inversion are not provided")
    End If

    'if nullValue param was provided, fill the datable with it 
    If nullValue <> "" Then
        For Each dr As DataRow In dt2.Rows
            For Each dc As DataColumn In dt2.Columns
                If dr(dc.ColumnName).ToString() = "" Then
                    dr(dc.ColumnName) = nullValue
                End If
            Next
        Next
    End If

    Return dt2

End Function

''' <summary>
''' Sorts a list of strings checking to see if they are numeric or date types.
''' </summary>
''' <param name="list"></param>
''' <param name="srt"></param>
''' <returns></returns>
''' <remarks></remarks>
Private Shared Function SortValues(ByVal list As List(Of String), ByVal srt As Sort) As List(Of String)

    Dim tickList As List(Of Long) = Nothing
    Dim dblList As List(Of Double) = Nothing

    ' Figure out how to sort columnX
    For Each s As String In list
        Dim colDate As Date = Nothing
        If Date.TryParse(s, colDate) Then
            tickList = New List(Of Long)
            Exit For
        End If
    Next

    Dim dateTicks As Long

    If Not tickList Is Nothing Then
        For Each s As String In list
            dateTicks = DateTime.Parse(s).Ticks
            If Not tickList.Contains(dateTicks) Then
                tickList.Add(dateTicks)
            End If
        Next

        If srt = Sort.DESC Then
            tickList.Sort()
            tickList.Reverse()
        ElseIf srt = Sort.ASC Then
            tickList.Sort()
        End If

        list.Clear()
        For Each lng As Long In tickList
            list.Add(New Date(lng).ToString("G"))
        Next
    Else
        Dim dbl As Double = Nothing

        For Each s As String In list
            If IsNumeric(s) Then
                dblList = New List(Of Double)
            End If
        Next

        If Not dblList Is Nothing Then
            'Doubles or Integers
            For Each s As String In list
                dbl = Val(s)
                If Not dblList.Contains(dbl) Then
                    dblList.Add(dbl)
                End If
            Next

            If srt = Sort.DESC Then
                dblList.Sort()
                dblList.Reverse()
            ElseIf srt = Sort.ASC Then
                dblList.Sort()
            End If

            list.Clear()
            For Each d As Double In dblList
                list.Add(d.ToString)
            Next
        Else
            'Strings
            If srt = Sort.DESC Then
                list.Sort()
                list.Reverse()
            ElseIf srt = Sort.ASC Then
                list.Sort()
            End If
        End If

    End If

    Return list

End Function

这篇关于填充Datagrid和Sql查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆