【问题标题】:SQL Query builder utilitySQL 查询生成器实用程序
【发布时间】:2014-08-04 13:09:54
【问题描述】:

我有一组列和表,在各自的下拉列表中,我正在编写代码以根据表列选择生成动态 SQL

它适用于简单的 Select 语句,但在多重连接的情况下,我试图找出处理右连接和左连接的语法。

请帮忙..这是 SQL 语法错误

1)
(Select dbo.Employee.Dept_ID,dbo.Employee.Emp_ID,dbo.Employee.Emp_Name,dbo.Employee_DataVal.DeptNo,
dbo.Employee_DataVal.EmpName,dbo.Employee_DataVal.EmpNo,dbo.Employee_DataVal.Salary,dbo.Emp_Sal.Emp_ID,dbo.Emp_Sal.Salary
FROM Employee
INNER JOIN Employee_DataVal
ON Employee.Dept_ID = Employee_DataVal.DeptNo
OR Employee_DataVal.EmpName = Employee.Emp_Name)
LEFT JOIN Emp_Sal
ON Employee.Emp_ID = Emp_Sal.Emp_ID

Incorrect syntax near the keyword 'LEFT'.

2)Select dbo.Employee.Dept_ID,dbo.Employee.Emp_ID,
dbo.Employee.Emp_Name,dbo.Employee_DataVal.DeptNo,
dbo.Employee_DataVal.EmpName,dbo.Employee_DataVal.EmpNo
,dbo.Emp_Sal.Emp_ID,dbo.Emp_Sal.Salary
FROM Employee INNER JOIN Employee_DataVal
ON Employee.Emp_ID = Employee_DataVal.EmpNo
AND Employee.Dept_ID = Employee_DataVal.DeptNo
LEFT JOIN Employee
ON Employee_DataVal.EmpName = Employee.Emp_Name

The objects "Employee" and "Employee" in the FROM clause have the same exposed names. Use correlation names to distinguish them.

PS:在 SQL server 上运行这个 sql

【问题讨论】:

  • 按照错误说的做 :-) 给你 db 一个临时名称,所以这个 FROM Employee INNER JOIN Employee_DataVal 变成 FROM Employee e INNER JOIN Employee_DataVal,然后只需在你的字段前加上前缀
  • 感谢您的快速响应,正如我所提到的,我必须构建一个动态查询,所以如果用户在不同的表 XTable 之间从 UI 添加右连接,那么我应该如何继续?语法明智并且在 java 中也以编程方式?

标签: java sql sql-server database


【解决方案1】:

这是处理基于字符串的复杂动态 SQL 字符串时的常见问题 - 正确处理字符串形式的 SQL 语法很困难,而且很容易造成 SQL 注入漏洞。

jOOQothers 等 SQL 构建器 API 非常适合此任务。我不确定您的问题到底是什么,但我们假设最后一个 LEFT JOIN 在您的查询中是可选的。你可以这样写一个查询:

List<Field<?>> c = new ArrayList<>(Arrays.asList(
    EMPLOYEE.DEPT_ID,
    EMPLOYEE.EMP_ID,
    EMPLOYEE.EMP_NAME,
    EMPLOYEE_DATAVAL.DEPTNO,
    EMPLOYEE_DATAVAL.EMPNAME,
    EMPLOYEE_DATAVAL.EMPNO,
    EMPLOYEE_DATAVAL.SALARY
));
Table<?> t = EMPLOYEE
   .join(EMPLOYEE_DATAVAL)
     .on(EMPLOYEE.DEPT_ID.eq(EMPLOYEE_DATAVAL.DEPTNO)
     .or(EMPLOYEE_DATAVAL.EMPNAME.eq(EMPLOYEE.EMP_NAME));

if (someCondition) {
    t = t.leftJoin(EMP_SAL).on(EMPLOYEE.EMP_ID.eq(EMP_SAL.EMP_ID));
    c.addAll(Arrays.asList(
        EMP_SAL.EMP_ID,
        EMP_SAL.SALARY
    ));
}

Result<?> result =
ctx.select(c)
   .from(t)
   .fetch();

【讨论】:

    【解决方案2】:

    直接讲语法错误:

    1. 此语句中的括号无效。删除它们将解决问题。
    2. 表 Employee 在 FROM 子句中使用了两次。您必须为这些表起别名才能使用。

      选择 dbo.Employee.Dept_ID,dbo.Employee.Emp_ID, dbo.Employee.Emp_Name,dbo.Employee_DataVal.DeptNo, dbo.Employee_DataVal.EmpName,dbo.Employee_DataVal.EmpNo ,dbo.Emp_Sal.Emp_ID,dbo.Emp_Sal.Salary FROM Employee e1 INNER JOIN Employee_DataVal 开 e1.Emp_ID = Employee_DataVal.EmpNo AND e1.Dept_ID = Employee_DataVal.DeptNo 左加入员工 e2 ON Employee_DataVal.EmpName = e2.Emp_Name

    谈到您的更广泛的问题,通用 SQL 查询生成器的概念很常见,并且已经有多个实现。您不会在诸如此类的论坛中找到完整的实施指南。

    干杯!

    【讨论】:

    • “通用 SQL 查询生成器的概念很常见,并且已经有好几个实现了”你能推荐一些相同的链接吗?这真的会给我进一步前进的提示!谢谢
    • 也许这个 codeproject 帖子会让你流连忘返。 codeproject.com/Articles/13419/…
    【解决方案3】:

    您使用的左连接与自连接相同。这实际上是造成问题。

    【讨论】:

      【解决方案4】:

      在第一种情况下,由于错误的) 出现在错误的位置,如下所示;这使得查询结束,所以LEFT JOIN 抛出一个错误。 ) 必须在查询的末尾。

      FROM Employee
      INNER JOIN Employee_DataVal
      ON Employee.Dept_ID = Employee_DataVal.DeptNo
      OR Employee_DataVal.EmpName = Employee.Emp_Name ) <--Here
      LEFT JOIN Emp_Sal
      

      在第二种情况下,您正在尝试对同一张表执行self join,因为错误已经建议您,您需要像使用correlation names 一样

      FROM Employee emp1 <-- Here used a table alias emp1
      INNER JOIN Employee_DataVal ed
      ON emp1.Emp_ID = ed.EmpNo
      AND emp.Dept_ID = ed.DeptNo
      LEFT JOIN Employee emp2 <-- Here used a different table alias emp2
      ON ed.EmpName = emp2.Emp_Name
      

      此外,LEFT JOIN Employee 在这里没有任何意义,可以简单地修改为下面的代码

      FROM Employee emp1 
      INNER JOIN Employee_DataVal ed
      ON emp1.Emp_ID = ed.EmpNo
      AND emp.Dept_ID = ed.DeptNo
      AND emp.Emp_Name = ed.EmpName <-- here by adding another join condition
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多