Edit Data. Create Cell Editors. Validate User Input

获取和修改代码中的单元格值

提醒:仅当网格及其列已完全初始化时,才使用以下方法。如果您需要在表单仍在加载时调用这些方法,请调用ForceInitialize()方法来强制Grid完成初始化。

单元格读取单元格值更改单元格值
focused cellColumnView.GetFocusedValue ColumnView.FocusedValueColumnView.SetFocusedValue
cell of a focused rowColumnView.GetFocusedRowCellValue ColumnView.GetFocusedRowCellDisplayTextColumnView.SetFocusedRowCellValue
Any row cellColumnView.GetRowCellValue ColumnView.GetRowCellDisplayTextColumnView.SetRowCellValue
cell value in an underlying data sourceColumnView.GetListSourceRowCellValue
The currently edited cellColumnView.EditingValueColumnView.EditingValue

ColumnView.CellValueChanging和ColumnView。当用户更改单元格值时,会引发CellValueChanged事件。

  • 下面的代码检索属于“ID”列和第三个数据行(行句柄等于2)的单元格的值。
string cellValue;
cellValue = gridView1.GetRowCellValue(2, "ID").ToString();
  • 此代码返回当前关注单元格内显示的文本。
string cellValue = gridView1.GetFocusedDisplayText();
  • 此示例更改聚焦单元格的值。
gridView1.SetRowCellValue(gridView1.FocusedRowHandle, gridView1.FocusedColumn, "New Value");
//or
gridView1.SetFocusedValue("New Value");
  • 网格单元格编辑器等待用户将焦点移动到另一个单元格或行,然后才接受其新值。下面的代码强制编辑器立即更新其值。
BaseEdit edit = null;
    private void gridView1_ShownEditor(object sender, EventArgs e)
    {
        GridView view = sender as GridView;
        edit = view.ActiveEditor;
        edit.EditValueChanged += edit_EditValueChanged;       
    }

    void edit_EditValueChanged(object sender, EventArgs e)
    {
        gridView1.PostEditor();
    }

    private void gridView1_HiddenEditor(object sender, EventArgs e)
    {
        edit.EditValueChanged -= edit_EditValueChanged;
        edit = null;
    }
  • 在Change column cell values based on other column’s values demo中,如果输入的“Length”大于10,则会自动选中“Mark”列下的复选框,否则会清除。
gridView.CellValueChanged += (sender, e) => {
    GridView view = sender as GridView;
    if (e.Column.FieldName == "Length") {
        double doubleVal = (double)e.Value;
        view.SetRowCellValue(e.RowHandle, "Mark", doubleVal > 10);
    }
};

单元格编辑器

默认单元格编辑器

网格列使用数据编辑器来显示和编辑数据。列根据其显示的数据类型自动创建编辑器。例如,显示日期时间值的列使用DateEdit。
在这里插入图片描述
在这里插入图片描述

在设计时替换默认单元格编辑器

调用列的智能标记菜单并使用GridColumn.ColumnEdit属性的下拉列表,以创建新编辑器或选择现有编辑器。
在这里插入图片描述

您还可以运行数据网格设计器并打开其在位编辑器存储库页面以访问所有在位编辑器。您可以添加、自定义和删除存储库项目。

在这里插入图片描述

创建单元格编辑器并将其指定给代码中的列

    // Creates a 'ToggleSwitch' repository item.            
    RepositoryItemToggleSwitch edit = new RepositoryItemToggleSwitch();
    // Adds the repository item to the grid's RepositoryItems collection. 
    gridControl.RepositoryItems.Add(edit);
    // Assigns the repository item to the 'Mark' column.
    gridView.Columns["Mark"].ColumnEdit = edit;

案例

如何在具有数值的列中显示进度条

下面的代码说明了如何使用ProgressBarControl作为整数“相关性”网格列的就地编辑器。用户可以点击或按住数字键盘“+”和“-”键来修改这些整数值。

using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraEditors.Repository;

// Create a repository item
RepositoryItemProgressBar ieProgress = new RepositoryItemProgressBar();
gridControl1.RepositoryItems.Add(ieProgress);
ieProgress.KeyPress += IeProgress_KeyPress;

// Assign the repository item
colRelevance.ColumnEdit = ieProgress;
// Or
private void GridView1_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e) {
    if (e.Column == colRelevance) e.RepositoryItem = ieProgress;
}

// Handle + and - key presses
private void IeProgress_KeyPress(object sender, KeyPressEventArgs e) {
    int i = 0;
    if (gridView1.ActiveEditor == null) return;

    if (e.KeyChar == '+') {
        i = (int)gridView1.ActiveEditor.EditValue;
        if (i < 100)
            gridView1.ActiveEditor.EditValue = i + 1;
    }
    if (e.KeyChar == '-') {
        i = (int)gridView1.ActiveEditor.EditValue;
        if (i > 0)
            gridView1.ActiveEditor.EditValue = i - 1;
    }
}

如何在单元格中显示按钮

如何在单元格中显示按钮编辑和删除行的单元格命令演示有一个带有按钮编辑单元格编辑器的“命令”列。编辑器有两个按钮:Edit调用Edit Form,Delete删除当前行
在这里插入图片描述

    // Create the Commands column editor
    RepositoryItemButtonEdit commandsEdit = new RepositoryItemButtonEdit { AutoHeight = false, Name = "CommandsEdit", TextEditStyle = TextEditStyles.HideTextEditor };
    commandsEdit.Buttons.Clear();
    commandsEdit.Buttons.AddRange(new EditorButton[] {
    new EditorButton(ButtonPredefines.Glyph, "Edit", -1, true, true, false, ImageLocation.MiddleLeft, DemoHelper.GetEditImage()),
    new EditorButton(ButtonPredefines.Glyph, "Delete", -1, true, true, false, ImageLocation.MiddleLeft, DemoHelper.GetDeleteImage())});
    grid.RepositoryItems.Add(commandsEdit);

    // Create an unbound Commands column
    GridColumn _commandsColumn = gridView.Columns.AddField("Commands");
    _commandsColumn.UnboundDataType = typeof(object);
    _commandsColumn.Visible = true;
    _commandsColumn.Width = 100;

    // Hide commandsColumn from EditForm
    _commandsColumn.OptionsEditForm.Visible = DevExpress.Utils.DefaultBoolean.False;

    // Display commands only for the focused row
    gridView.CustomRowCellEdit += (s, e) => {
        if (e.RowHandle == gridView.FocusedRowHandle && e.Column == _commandsColumn)
            e.RepositoryItem = commandsEdit;
    };
    gridView.CustomRowCellEditForEditing += (s, e) => {
        if (e.RowHandle == gridView.FocusedRowHandle && e.Column == _commandsColumn)
            e.RepositoryItem = commandsEdit;
    };

    // Allow only commandsColumn to be edited
    gridView.ShowingEditor += (s, e) => {
        e.Cancel = gridView.FocusedColumn != _commandsColumn;
    };

    gridView.OptionsEditForm.ShowOnDoubleClick = DevExpress.Utils.DefaultBoolean.False;
    gridView.OptionsEditForm.ShowOnEnterKey = DevExpress.Utils.DefaultBoolean.False;
    gridView.OptionsEditForm.ShowOnF2Key = DevExpress.Utils.DefaultBoolean.False;
    gridView.OptionsBehavior.EditingMode = GridEditingMode.EditFormInplace;

    // Perform a specific action when an EditorButton is clicked
    commandsEdit.ButtonClick += (s, e) => {
        switch (e.Button.Caption) {
            case "Edit":
                // Start editing a row using EditForm
                gridView.CloseEditor();
                gridView.ShowEditForm();
                break;
            case "Delete":
                // Delete focused row
                gridView1.DeleteRow(gridView1.FocusedRowHandle);
                break;
        }
    };

如何对同一列的单元格使用不同的编辑器

在Assign就地编辑器动态演示中,“Length”列接收SpinEdit或CalcEdit编辑器,具体取决于是否选中了“Mark”列下的复选框。

RepositoryItemSpinEdit spinEdit = new RepositoryItemSpinEdit();
RepositoryItemCalcEdit calcEdit = new RepositoryItemCalcEdit();
grid.RepositoryItems.Add(spinEdit);
grid.RepositoryItems.Add(calcEdit);
gridView.Columns["Length"].ShowButtonMode = ShowButtonModeEnum.ShowAlways;

// Handle this event to assign editors to individual cells
gridView.CustomRowCellEdit += (sender, e) => {
    GridView view = sender as GridView;
    if (e.Column.FieldName == "Length") {
        bool boolVal = (bool)view.GetRowCellValue(e.RowHandle, "Mark");
        if (boolVal)
            e.RepositoryItem = spinEdit;
        else
            e.RepositoryItem = calcEdit;
    }
};

在网格单元格中显示任何UI控件

使用RepositoryItemAnyControl将UI控件嵌入到网格单元格中。控件必须实现 DevExpress.XtraEditors.CustomEditor.IAnyControlEdit 接口。DevExpress仪表控制和图表控制实现了开箱即用的界面。您需要手动实现此接口,以便在网格单元格中嵌入其他UI控件。

下图显示了带有嵌入式DevExpress Chart控件的网格单元。
在这里插入图片描述

使用不同的编辑器显示和编辑单元值

列使用相同的编辑器来显示和编辑其值。处理CustomRowCellEditForEditing事件以使用不同的编辑器来显示和编辑列值。
以下示例演示如何使用ProgressBarControl在“数量”列中显示数值,以及如何使用SpinEdit编辑单元格值。

// Creates two repository items.
            RepositoryItem editorForDisplay, editorForEditing;
            // Initializes the repository items.
            editorForDisplay = new RepositoryItemProgressBar();
            editorForEditing = new RepositoryItemSpinEdit();
            // Forces the grid to initialize its settings.
            gridControl1.ForceInitialize();
            // Adds the repository items to the grid's RepositoryItems collection.
            gridView1.GridControl.RepositoryItems.AddRange(
                new RepositoryItem[] { editorForDisplay, editorForEditing });
            // Assign the 'Progress Bar' repository item to the numeric 'Quantity' column.
            gridView1.Columns["charge_total"].ColumnEdit = editorForDisplay;
            /* Handles the 'CustomRowCellEditForEditing' event to create a Spin Editor
                * when a user edits a cell value in the 'Quantity' column.
                */
            gridView1.CustomRowCellEditForEditing += (sender, e) => {
                if (e.Column.FieldName == "charge_total")
                    e.RepositoryItem = editorForEditing;
            };

API管理单元格编辑器

APDescription
BaseView.ShowEditor调用聚焦单元格的编辑器。
BaseView.HideEditor关闭活动编辑器并放弃所做的更改
BaseView.CloseEditor保存所做的任何更改并关闭活动编辑器。
BaseView.PostEditor在不关闭活动编辑器的情况下保存所做的任何更改。
BaseView.ActiveEditor获取活动编辑器。
ColumnView.ShownEditor当网格激活在位编辑器时激发。以下示例显示了当用户开始编辑OrderDate列中的值时,如何指定当前日期并打开DateEdit的下拉列表。
ColumnView.HiddenEditor当在位编辑器关闭时激发。以下示例演示如何在关闭活动编辑器后将单元格焦点移动到列中的下一个单元格。用户无需将焦点从一个单元格移动到另一个单元格即可编辑列中的单元格值。
OptionsBehavior.EditorShowMode指定鼠标如何激活单元格编辑器。以下示例显示了如何始终显示编辑器按钮,并允许用户在第一次单击时单击编辑器按钮:

在单独的表单中编辑数据

编辑表单模式

用户可以使用“编辑表单”而不是在位编辑器来编辑数据行。双击网格行或按Enter键或F2键调用编辑窗体。使用EditingMode属性指定编辑模式。
在这里插入图片描述
基于网格的视图支持以下编辑表单显示模式:

  • 浮动模态形式(默认)
  • 带数据行的内联编辑表单(网格在编辑的数据行下方显示编辑表单)
  • 内联编辑窗体(网格不显示编辑的行)

Edit Form API

APIDescription
GridOptionsBehavior.EditingModeAllows you to turn on the Edit Form and specify its display mode.
GridView.ShowEditForm GridView.HideEditFormAllow you to display and hide the Edit Form.
GridOptionsEditForm.ActionOnModifiedRowChangeSpecifies whether to show confirmation dialogs when users modify records.
GridOptionsEditForm.ShowUpdateCancelPanelSpecifies whether to display the Update and Cancel buttons. Ctrl+Enter saves the changes. Esc discards the changes.
GridOptionsEditForm.BindingModeSpecifies whether to pass changes to the Grid immediately after a user moves focus to another field in the Edit Form, or after all changes have been accepted.
GridOptionsEditForm.FormCaptionFormatSpecifies the caption of a Floating Edit Form.
GridView.EditFormShowingFires before the Edit Form is displayed. Handle this event to hide the Edit Form and prevent a user from editing values in certain cells. The following example prevents a user from editing cell values in even rows:

更改编辑表单字段中的值–实现自定义编辑逻辑

编辑窗体是一个包含数据编辑器(字段)的容器控件。数据编辑器绑定到数据记录中相应的字段/属性。执行以下操作之一以指定这些数据编辑器的值:

  • 创建一个自定义的编辑表单并实现数据编辑器所需的行为。
  • 处理GridView.EditFormPrepared事件,用于访问和自定义显示在编辑窗体中的编辑器。

以下示例处理EditFormPrepared事件,以便在用户打开编辑表单时聚焦“第一个”日期编辑器。

using DevExpress.XtraGrid.Views.Grid;

// ...
gridView.OptionsBehavior.EditingMode = GridEditingMode.EditForm;

DateEdit dateEdit = null;
gridView.EditFormPrepared += (s, e) => {
    // The 'e.BindableControls' collection contains the editors in the Edit Form.
    foreach (Control item in e.BindableControls) {
        dateEdit = item as DateEdit;
        if (dateEdit != null) {
            // Focuses the Date Editor.
            dateEdit.Select();
            return;
        }
    }
};

更改编辑表单布局

Grid控件根据以下规则创建“编辑表单”:

  • “编辑窗体”为每个可见的可编辑列显示一个编辑器。
  • 如果列使用不同的编辑器来编辑和显示单元格值,则“编辑窗体”将显示“编辑”模式中使用的编辑器。
  • 编辑表单的客户端区域有一个包含三列的表格布局。每个编辑器(MemoEdit和PictureEdit除外)都占用表中的一个单元格。
  • MemoEdit编辑器横向跨越所有布局列,纵向跨越三个布局行。
  • PictureEdit编辑器横向跨越两个布局列,纵向跨越三个布局行

调用数据网格设计器并切换到“编辑窗体设计器”页面以自定义“编辑窗体”的布局。
在这里插入图片描述

编辑表单API

APIDescription
GridColumn.OptionsEditForm使用此属性可以自定义在“编辑窗体”中显示的列编辑器。
OptionsColumnEditForm.UseEditorColRowSpan禁用此选项可以为列的编辑器设置自定义列和行跨度。
OptionsColumnEditForm.ColumnSpan / OptionsColumnEditForm.RowSpan指定列编辑器所跨越的列和行数。
OptionsColumnEditForm.Caption / OptionsColumnEditForm.CaptionLocation允许您指定编辑器的标题及其位置。
OptionsColumnEditForm.Visible / OptionsColumnEditForm.VisibleIndex使用这些属性可以隐藏编辑器或指定其在其他编辑器中的位置。
OptionsColumnEditForm.StartNewRow启用此选项可在新行上显示编辑器。

创建自定义编辑表单

  • 创建用户控件。从EditFormUserControl类继承它。如果用户控件有分部类,则它们还必须继承EditFormUserControl类。
  • 创建编辑表单UI(根据需要自定义用户控件)。
  • 使用父类的BoundFieldName和BoundPropertyName属性将编辑器绑定到数据源字段。
  • 将自定义编辑窗体的实例分配给网格的GridOptionsEditForm.CustomEditFormLayout属性。
  • 将自定义编辑形状的单独实例指定给每个局部视图,以便在主详细信息模式下的局部视图中使用自定义编辑形状。
using DevExpress.XtraGrid.Views.Grid;
// Custom Edit Form
public class AdvancedEditForm : EditFormUserControl {
    public AdvancedEditForm() {
        InitializeComponent();
        // Binds the 'EditValue' of the 'textEdit3' editor to the Price field.
        this.SetBoundFieldName(textEdit3, "Price");
        this.SetBoundPropertyName(textEdit3, "EditValue");
    }
}

// Enables the Custom Edit Form.
gridView1.OptionsEditForm.CustomEditFormLayout = new AdvancedEditForm();

// Enables the Custom Edit Form to edit values in detail views in Master-Detail mode.
void gridControl1_ViewRegistered(object sender, DevExpress.XtraGrid.ViewOperationEventArgs e) {
    GridView detailCloneView = e.View as GridView;
    if(detailCloneView.LevelName == "Order_Details")
        detailCloneView.OptionsEditForm.CustomEditFormLayout = new AdvancedEditForm(); 
}

管理用户输入

禁用某些单元格

可以禁止用户根据条件编辑网格或列中的单元格值。

全局网格设置

  • 禁用视图的选项OptionsBehavior.Editable 选项使所有单元格只读。
  • 启用列的OptionsColumn.ReadOnly设置使其单元格为只读。
  • 禁用列的OptionsColumn.AllowEdit和OptionsColumn。AllowFocus选项禁用其单元格。

根据条件禁用单元格

使用“ Disabled Cell Behavior”可以禁用行中满足特定条件的单元格。禁用的单元格显示为灰色,无法编辑。
处理ColumnView.ShowingEditor事件,并将其Cancel参数设置为true。

以下示例处理ShowingEditor事件,以在Country列中的值为“Germany”时禁用关注行中的单元格。

using DevExpress.XtraGrid.Views.Grid;

private void gridView1_ShowingEditor(object sender, System.ComponentModel.CancelEventArgs e) {
   GridView view = sender as GridView;
   string cellValue = view.GetRowCellValue(view.FocusedRowHandle, colCountry).ToString();
   if (cellValue == "Germany")
       e.Cancel = true;
}

以下示例阻止用户编辑奇数行中“ID”列中的单元格:

gridView.ShownEditor += (s, e) => {
    GridView view = s as GridView;
    view.ActiveEditor.Properties.ReadOnly =
        gridView.FocusedColumn.FieldName == "ID" && gridView.FocusedRowHandle % 2 == 0;
};

禁用基于条件编辑表单字段

使用以下技术之一禁用“编辑表单”中的字段:

  • 处理GridView.EditFormPrepared事件,使用e.BindableControls属性可以访问所需的编辑器并禁用其“可编辑”属性。
  • 创建自定义编辑窗体并在EditFormUserControl中指定编辑器的行为
<think>好的,我现在要解决用户遇到的SQL错误42601,特别是在使用DBeaver时出现的“syntax error at end of input”问题。首先,我需要了解这个错误通常是什么原因引起的。根据之前的知识,SQL状态码42601通常表示语法错误,而错误信息中的“end of input”意味着解析器在输入结束时遇到了不符合预期的结构,可能某个语句没有正确结束。 用户提到在使用DBeaver时发生这个错误,我需要考虑DBeaver是否有特定的配置或行为可能导致这样的问题。首先,可能的情况是SQL语句中存在未闭合的引号、括号,或者缺少分号。例如,如果在语句末尾漏掉了分号,尤其是在执行多个语句时,解析器可能无法正确识别语句的结束,导致在输入结束时抛出错误。 接下来,我需要参考用户提供的引用内容。引用[1]中的例子是创建序列时出现语法错误,提示在'sequence bmsql_hist_id_seq'附近有错误。这可能是因为使用的数据库(如OceanBase)不支持标准的CREATE SEQUENCE语句,或者语法有差异。引用[2]展示了MySQL中修改密码的错误,用户使用了错误的语法,后来改用ALTER USER成功,这说明不同数据库版本的语法可能有差异。引用[4]提到通过用括号包裹子查询解决UNION和ORDER BY的问题,这提示某些情况下需要特定的语法结构。 结合这些引用,可能的解决方案包括检查SQL语句是否符合当前数据库的语法规范,确保所有括号、引号正确闭合,语句以分号结束,以及子句的正确顺序(比如UNION后的ORDER BY可能需要用括号包裹子查询)。此外,DBeaver可能在某些情况下自动生成的SQL语句存在格式问题,需要手动调整。 另外,用户可能混淆了不同数据库的语法,比如在PostgreSQL中使用特定于MySQL的语句,或者反之。因此,确认目标数据库类型和版本,并查阅相应的文档是非常重要的步骤。同时,DBeaver的日志或错误详情可能提供更具体的信息,帮助定位问题所在。 可能的步骤包括: 1. 检查SQL语句是否有未闭合的括号或引号。 2. 确保语句末尾有分号,特别是多个语句时。 3. 确认使用的数据库类型,并查阅其文档验证语法是否正确。 4. 对于复杂的查询,如使用UNION或子查询,确保结构正确,可能需要用括号包裹。 5. 在DBeaver中查看完整的错误信息,可能会有更具体的提示。 6. 如果使用预编译语句或动态SQL,检查变量拼接是否正确。 例如,如果用户写了一个SELECT语句,但没有FROM子句,或者在INSERT语句中VALUES的数量与列不匹配,这些都可能导致解析器在结束时发现结构不完整。此外,DBeaver可能在某些模式下自动添加限制,比如在分页查询中的LIMIT子句,如果语法不正确也会导致错误。 还需要考虑是否有保留字被用作标识符而未加引号,或者表名、列名含有特殊字符未正确转义。例如,使用"user"作为表名在PostgreSQL中可能需要加双引号,否则会解析为关键字导致错误。 最后,建议用户分段测试SQL语句,逐步排查问题部分,或者使用DBeaver的SQL编辑器中的语法高亮和自动补全功能,帮助发现明显的语法错误。</think>### SQL错误42601(语法错误)分析与解决方案 **错误特征**:`SQL Error [42601]: syntax error at end of input` 表示解析器在SQL语句结尾处发现不符合预期的语法结构,常见于以下场景: --- ### 一、常见原因及排查步骤 1. **未闭合的符号** 检查是否缺少闭合符号: - 括号 `()` 未闭合:$SELECT (col1 + col2 FROM table$(缺少右括号) - 引号 `'` 或 `"` 未闭合:$INSERT INTO table VALUES ('text)$ - 注释符未闭合(如`/* ... */`) 2. **语句未正确终止** - 多语句执行时缺少分号 `;` ```sql CREATE TABLE t1 (id INT); -- 正确 CREATE TABLE t2 (name VARCHAR(10)) -- 缺少分号 ``` 3. **子句顺序或结构错误** - `UNION` 后直接使用 `ORDER BY` 需用括号包裹子查询[^4]: ```sql (SELECT col1 FROM tb1 ORDER BY col1) UNION (SELECT col1 FROM tb2 ORDER BY col1); ``` - `GROUP BY`/`HAVING` 出现在 `WHERE` 前会导致解析失败。 4. **数据库方言差异** - **OceanBase** 不支持 `CREATE SEQUENCE` 语法(需改用其他方式生成序列)[^1] - **PostgreSQL** 要求 `ALTER USER` 而非 `SET PASSWORD`[^2] 5. **DBeaver特定问题** - 连接配置错误(如选择错误的数据库类型) - 自动生成的SQL存在格式问题(如分页查询中多余的符号) --- ### 二、解决方案 1. **基础检查** - 使用代码编辑器或DBeaver的语法高亮功能检查符号闭合。 - 在复杂查询中逐段注释排查问题区域。 2. **适配数据库语法** - 确认目标数据库类型(如MySQL、PostgreSQL、OceanBase)并查阅官方文档。 - 示例修正(OceanBase建表错误[^1]): ```sql -- 错误:CREATE SEQUENCE bmsql_hist_id_seq; -- 正确:使用AUTO_INCREMENT替代(MySQL/OceanBase兼容) CREATE TABLE t (id INT AUTO_INCREMENT PRIMARY KEY); ``` 3. **规范子查询结构** 对含 `UNION` 或 `ORDER BY` 的查询使用括号包裹[^4]: ```sql (SELECT col1 FROM tb1 ORDER BY col1 LIMIT 10) UNION ALL (SELECT col1 FROM tb2 ORDER BY col1 LIMIT 10); ``` 4. **检查保留字与特殊字符** 对包含保留字(如`user`、`order`)的标识符添加引号: ```sql SELECT "user" FROM "order"; -- PostgreSQL SELECT `user` FROM `order`; -- MySQL ``` --- ### 三、DBeaver调试建议 1. **查看完整错误日志** 右键点击错误信息 → `Copy Error` 获取完整上下文。 2. **执行计划验证** 使用 `EXPLAIN` 分析查询结构(如PostgreSQL支持 `EXPLAIN ANALYZE`)。 3. **连接配置检查** - 确认驱动版本与数据库匹配(如PostgreSQL JDBC驱动)。 - 测试直接通过数据库命令行执行相同语句,排除工具干扰。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值