由于检索到的列名,网格视图不接受我的数据绑定,或者可能是我的错误

Grid View not accepting my databind due to retrieved column names, or maybe an error on my part

我需要弄清楚为什么我的网格视图不接受我的数据绑定。我 运行 遇到的第一个问题是它需要动态创建,并且必须将我的 logic/structure 修改为现在的样子。

我认为问题在于从 PestList 中的初始 SQL 查询返回 BindGridView 的实际结果集,如下所示。我一直在尝试一些事情,比如重新处理 selects、多个 SQL 查询等。我还尝试将列合并并转换为带有 CAST(value as Varchar) 的字符串等。

我的下一个想法是尝试添加一种方法来分段构建 SQL 字符串,但我不确定我是否再以正确的方式进行此操作。

这是我在FlameRobin中构建的使用初始集sql select的方法(table充满了测试数据,方法名称已略有更改):

Private Sub getPestList()

    tempVal = "With tmp1(Field) As " +
    " (select distinct t2.ORCHARDDETAILID from PESTMONITOR t2), " +
    " tmp2(MyPivot) As " +
    " (select 'iif(t2.ORCHARDDETAILID = ' || Field || ', t2.QUANTITY, 0) as ' || MyField || ' ' from tmp1) " +
    " Select 'select t2.MONITORDATE, '||list(distinct MyPivot)||' from PESTMONITOR t2 order by 1' from PESTMONITOR cross join tmp2"

    Using execSQL As New FbCommand((tempVal), con)
        tempVal = execSQL.ExecuteScalar()
    End Using
End Sub

这会根据 table 中的信息生成我的动态 SQL 字符串,并将其传递给 tempVal,结果如下(2 selects 和交叉连接):

现在是的,SQL 看起来很时髦,我对格式表示歉意,所以我也会在这里粘贴内联 sql:

with tmp1(MyFieldName) as (select distinct t2.ORCHARDDETAILID from PESTMONITOR t2), tmp2(MyPivotSource) as (select 'iif(t2.ORCHARDDETAILID = ' ||MyFieldName|| ', t2.QUANTITY, 0) as ' || MyFieldName || ' ' from tmp1) select 'select t2.MONITORDATE, '||list(distinct MyPivotSource)||' from PESTMONITOR t2 order by 1' from PESTMONITOR cross join tmp2

但我需要这样做才能 运行 以下内容:

Private Sub GridView()
    Try

        getPestList()

        Dim sql = tempVal

        Dim dt As New DataTable
        Dim da As New FbDataAdapter(sql, con)

        da.Fill(dt)

        If dt.Rows.Count > 0 Then
            Dim pivotedTable As DataTable = PivotTable(dt)
            gvPCL.DataSource = pivotedTable
            gvPCL.DataBind()

        End If
    Catch ex As System.Data.SqlClient.SqlException
        Dim msg As String = "Fetch Error:"
        msg += ex.Message
        Throw New Exception(msg)

    End Try
End Sub

这会使用传入 FbDataAdapter 的变量填充我的 GridView

预期结果应该是:

初始Sql结果:

select t2.MONITORDATE, iif(t2.ORCHARDDETAILID = 819, t2.QUANTITY, 0) as 819 ,iif(t2.ORCHARDDETAILID = 836, t2.QUANTITY, 0) as 836 ,iif(t2.ORCHARDDETAILID = 837, t2.QUANTITY, 0) as 837  from PESTMONITOR t2 order by 1

第二个 sql 结果,以及 GridView(在数据绑定之后)应该显示这个 table:

            819         836         837                 
01.01.2019  0.000000    1.000000    0.000000
02.01.2019  0.000000    1.000000    0.000000
03.01.2019  0.000000    1.000000    0.000000
04.01.2019  0.000000    1.000000    0.000000
05.01.2019  0.000000    1.000000    0.000000
06.01.2019  0.000000    1.000000    0.000000
07.01.2019  0.000000    0.000000    1.000000
14.01.2019  0.000000    4.000000    0.000000
13.06.2019  2.000000    0.000000    0.000000
13.06.2019  3.000000    0.000000    0.000000
14.06.2019  1.000000    0.000000    0.000000

还有一两件事正在发生,但它们不会影响当前问题的任何进展。要点是在所有日期的块号上显示所有陷阱的计数。 (可以是1也可以是1001)

我在执行 da.Fill(dt) 时收到的错误如下:

Dynamic SQL Error
SQL error code = -104
Token unknown - line 1, column 73
819

所以这是设置错误列名的地方

… select t2.MONITORDATE, iif(t2.ORCHARDDETAILID = 819, t2.QUANTITY, 0) as 819 … 

为什么我的列名不能是数字?我不得不在列周围手动插入双引号。显示上面的结果网格。

我试过弄乱 "' 以及这些的组合来尝试逃避它,因为我将其设置为变量 tempVal="SQL HERE" 并且如果我添加任何声明,该声明将完全中断。

我正在考虑使用块函数,目前正在测试将 selects 合并到 exec block stmt and/or s-proc 中的方法,以解决 "" 中的问题IDE

编辑:感谢 Mark 指出我似乎没有意识到的标识符限制。我已经能够在没有任何手动干预的情况下更正错误,方法是在列使用行值别名之前附加一个字符,如下所示:``` ' || [a-z/A-Z] ||我的价值|| ''。我也许可以用代码中的 substr 或类似的东西将其删除,但如果不是世界末日,我也可以做到。鉴于此,我接受他的回答是正确的。

编辑 2:这个问题在技术上得到了回答,但这里是我想要帮助澄清的截图,正如用户在 Marks answer 下的评论中所建议的那样。IDE View of the issue after adding quotes to specify value as a string。

如您所见,这就是我为此苦苦挣扎的原因。以及为什么我认为逐行单独构建它而不是普通的 SQL 语句会是更好的方法。我来自 C#/MySQL 背景,我基本上是在学习 运行 遇到麻烦并需要修复它,它离我想要的位置很远,但它已经到了。

对于它的价值,感谢您花时间阅读它并尝试弄清楚它是什么。

Final Edit/Note:它现在完全正常工作,达到预期的 100%。错误是由于没有完全理解 SQL 中设置为列名的列标识符约束/变量需要定义为字符串,在这种情况下使用双引号 ""' … '""

列或别名不能以数字开头,因为它必须符合 Firebird 2.5 语言参考中 Identifiers 中记录的规则。常规标识符必须以 ASCII a-z 或 A-Z 开头,因此不能以数字开头。

如果要使用数字,则必须使用带引号的标识符,并用双引号将别名括起来。

您需要使用 "" 来转义双引号,或者在您的代码中使用 " (select 'iif(t2.ORCHARDDETAILID = ' || Field || ', t2.QUANTITY, 0) as ""' || MyField || '"" ' from tmp1) " +。即 || MyField || 之前的两个双引号和一个单引号 (""') 以及之后的一个单引号和两个双引号 ('"")。

不是答案,用于提供 "code"。

关于 IDE 屏幕截图 - 现在用鼠标光标将红色波浪下划线悬停并截取有关错误的信息工具提示 - 它到底说了什么? :-)

我建议您在创建元素数量未知的列表时使用不同的样式,在本例中 - mega-string 由数量未知的较短字符串组成。像这样:

X = "aaaaa"
  + "bbbbb"
  + "ccccc"
  + "ddddd"
;

而不是传统的 "bookish"

X = "aaaaaaaaaa" +
  "bbbbb" +
  "ccccccccccccc" + "ddddd";

请注意这里的加号是如何在下一个项目之前添加的,而不是隐藏在它之后的某处。

还要注意所有加号是如何在同一列上的 - 很容易发现它们并在那里检查(或不检查)。

这当然违背了"typographics"我们看小说书报看习惯了,看起来很奇怪等等。不过你试试吧。

在你的具体情况下 - 你似乎在编辑后的许多编辑之后只丢失了一个加号,这就是为什么 IDE 抱怨,你刚刚引入了两个字符串的语法错误他们之间没有任何关系。