实现递归时,SQL命令未正确结束错误

时间:2017-07-01 10:58:25

标签: sql sql-server

WITH TBL AS
(
   SELECT * FROM OUTPUT WHERE PRODUCT_ID = 5
   UNION ALL
   SELECT O.PRODUCT_ID,O.PRODUCT_NAME,O.PARENT_ID,O.PARENT_PRODUCT_NAME 
   FROM OUTPUT O
   JOIN TBL T1 ON O.PRODUCT_ID = T1.PARENT_ID
)
SELECT * FROM TBL
WHERE PRODUCT_ID <> 5
OPTION(MAXRECURSION 1000);

当我运行上面的代码时,我得到错误声明&#34; SQL命令未正确结束&#34;。请指导我。

3 个答案:

答案 0 :(得分:0)

您的查询没问题。 Here是RexTester中几乎完全相同的查询示例。

如果您收到错误,那么可能您在此代码之前有代码。那将导致错误。使用分号可以防止以后的代码出现问题。

首先,recursion子句应该明确列出列。不要使用select *select <column list>并期望两者匹配。所以列出列:

WITH TBL AS (
      SELECT O.PRODUCT_ID, O.PRODUCT_NAME, O.PARENT_ID, O.PARENT_PRODUCT_NAME
      FROM OUTPUT O
      WHERE PRODUCT_ID = 5
      UNION ALL
      SELECT O.PRODUCT_ID, O.PRODUCT_NAME, O.PARENT_ID, O.PARENT_PRODUCT_NAME 
      FROM OUTPUT O JOIN
           TBL T1
           ON O.PRODUCT_ID = T1.PARENT_ID
     )

其次,你的名字中不应该有PARENT_PRODUCT_NAME。你有PARENT_ID。用它来查找名称。

答案 1 :(得分:0)

来自Microsoft T-SQL documentation

  

当CTE在作为批处理一部分的语句中使用时,其前面的语句必须后跟分号。

在您之前的陈述/ class TextSettingsViewController: UIViewController { @IBOutlet fileprivate weak var picker: UIPickerView! weak var timer: Timer? deinit { timer?.invalidate() } override func viewDidLoad() { super.viewDidLoad() let timer = Timer(timeInterval: 0.1, repeats: true) { [unowned self] timer in let row = self.picker.selectedRow(inComponent: 0) print("selectedRow: \(row)") } // You need to add the timer to UITrackingRunLoopMode so it fires while scrolling the picker let runLoop = RunLoop.current runLoop.add(timer, forMode: .commonModes) runLoop.add(timer, forMode: .UITrackingRunLoopMode) self.timer = timer } } 之前添加分号(;)。总是用分号前置WITH语句可能是一种好习惯。

答案 2 :(得分:-1)

CTE定义要求以前的语句结束才能正确编译。所以你的代码应该像

; --you were missing this
WITH TBL AS
(
   SELECT * FROM OUTPUT WHERE PRODUCT_ID = 5
   UNION ALL
   SELECT O.PRODUCT_ID,O.PRODUCT_NAME,O.PARENT_ID,O.PARENT_PRODUCT_NAME 
   FROM OUTPUT O
   JOIN TBL T1 ON O.PRODUCT_ID = T1.PARENT_ID
)
SELECT * FROM TBL
WHERE PRODUCT_ID <> 5
OPTION(MAXRECURSION 1000);