Rails、Extjs 和 SQL Server
因此,我在 Rails 2.3.3 之上针对 SQL Server 数据库运行 Extjs。 我能够从数据库中提取数据并显示它,但无法创建、更新或销毁。
奇怪的是,它不会在尝试更新或删除时抛出控制台或任何其他错误 - 它只是失败。
创建时,会引发 InvalidStatement 错误,可能与未为新行分配适当的 ID 相关。 他们被分配了一个空 ID,当然它不允许作为身份值。
有人遇到过类似的事情吗? 关于使用 Extjs + SqlServer 创建、更新或销毁问题的解决方法有什么想法吗?
谢谢!
更新:
在相关表的 ID 字段上设置自动增量。 我收到的具体错误:
ActiveRecord::StatementInvalid (DVI::DatabaseError: 37000 (339) [ODBC SQL Server Driver][SQL Server] DEFAULT or NULL are not allowed as explicit identity values. INSERT INTO [table] ([username], [fullname], [ID], [password], [superuser]) VALUES('testing', 'testing', NULL, 'testing', 1)):
# ... ruby exceptions mostly springing from the sqlserver adapter ...
请注意,如果我弹出打开调试器并手动添加 ID,它工作正常...
UPDATE2:
在更新/销毁时,初始 POST 请求会使用正确的(修改后的)构造现场数据,并显示成功的响应。 但是,更新数据不会反映在后续的 GET 请求中。
深入研究日志,我们发现更新时生成的 SQL 存在以下问题:
Administrators Load (0.0ms) SELECT * FROM [Administrators] WHERE ([Administrators].[id] = '2')
EXECUTE (0.0ms) BEGIN TRANSACTION
Administrators Update (0.0ms) UPDATE [Administrators] SET [superuser] = 1 WHERE [id] = NULL
类似的问题也困扰着销毁请求。
这里发生了什么? 在提取适当的记录和执行操作之间,如何/为什么将 id 设置为 null?
请注意,即使我在调试器中手动执行此操作,即
(rdb:63) Administratiors.find(2).destroy
根据 ID 选择适当的行,但随后尝试从 id 为 NULL 的表中删除行,也会出现这种情况。 这当然会失败...
UPDATE3:
好的,所以我发现让删除操作起作用的唯一方法是滚动我自己的 SQL。 将 @admin.destroy 替换为
sql = ActiveRecord::Base.connection()
sql.begin_db_transaction
sql.execute("SELECT * FROM Administrators WHERE ([Administrators].[id] = #{params[:id]})");
sql.delete("DELETE FROM Administrators WHERE ([Administrators].[id] = #{params[:id]})");
sql.commit_db_transaction
按预期执行操作。
UPDATE4:
这也有效:
Administrators.delete(params[:id])
UPDATE5:
好的,现在 CRUD 在 Extjs 和 SQL Server 之间工作。 但这是一个丑陋的黑客行为(尤其是更新操作),我希望了解如何更干净地做到这一点:
# POST /administrators
def create
@administrator = Administrators.new(params[:administrators])
@administrator.ID = Administrators.all.length+1
respond_to do |format|
format.html
format.ext_json {render :json => @administrator.to_ext_json(:success => @administrator.save!)}
end
end
# PUT /administrators/1
def update
attrs_to_update = ""
params[:administrators].each {|k,v| attrs_to_update += "#{k} = \'#{v}\', "}
attrs_to_update = attrs_to_update.strip.chomp(",")
sql = ActiveRecord::Base.connection()
sql.begin_db_transaction
sql.execute("SELECT * FROM Administrators WHERE ([Administrators].[id] = #{params[:id]})");
sql.execute("UPDATE Administrators SET #{attrs_to_update} WHERE ([Administrators].[id] = #{params[:id]})");
sql.commit_db_transaction
render :json => @administrator.to_ext_json(:success => @administrator.update_attributes!(params[:administrators]))
end
# DELETE /administrators/1
def destroy
Administrators.delete(params[:id])
head :ok
end
关于如何清理它有什么想法吗? 或者再说一遍,为什么它一开始就不能开箱即用? :)
BUMP:
真的吗? 一定有人尝试过这个...
So I'm running Extjs on top of Rails 2.3.3 against a SQL Server DB. I'm able to pull data from the DB and display it, but I'm unable to create, update or destroy.
Oddly enough, it's not throwing console or any other errors on attempted updates or deletes -- it simply fails.
On create, an InvalidStatement error gets thrown, probably related to the fact that new rows aren't being assigned an appropriate ID. They're getting assigned a null ID, and of course it's not allowed as an identity value.
Has anybody encountered anything similar? Any ideas on workarounds for the issues on create, update or destroy using Extjs + SqlServer?
Thanks!
UPDATE:
Auto-increment is set on the ID field of the table in question. The specific error I'm getting handed back:
ActiveRecord::StatementInvalid (DVI::DatabaseError: 37000 (339) [ODBC SQL Server Driver][SQL Server] DEFAULT or NULL are not allowed as explicit identity values. INSERT INTO [table] ([username], [fullname], [ID], [password], [superuser]) VALUES('testing', 'testing', NULL, 'testing', 1)):
# ... ruby exceptions mostly springing from the sqlserver adapter ...
Note that if I pop open the debugger and add in the ID manually, it works fine...
UPDATE2:
On update/destroy, the initial POST request gets constructed with the proper (modified) field data, and a successful response is shown. However, the update data is not reflected in the subsequent GET request.
Digging into to the logs, we find the SQL generated on update has the following issue:
Administrators Load (0.0ms) SELECT * FROM [Administrators] WHERE ([Administrators].[id] = '2')
EXECUTE (0.0ms) BEGIN TRANSACTION
Administrators Update (0.0ms) UPDATE [Administrators] SET [superuser] = 1 WHERE [id] = NULL
A similar issue is plaguing the destroy requests.
What's going on here? How/why is the id getting set to null in between pulling the appropriate record and performing the operation?
Note that this is the behavior even when I manually perform this operation in the debugger, i.e.,
(rdb:63) Administratiors.find(2).destroy
selects the appropriate row based on ID, but then attempts to delete the row from the table whose id is NULL. Which of course fails...
UPDATE3:
OK, so the only way I've found to get the delete operation to work is to roll my own SQL. Replacing @admin.destroy with
sql = ActiveRecord::Base.connection()
sql.begin_db_transaction
sql.execute("SELECT * FROM Administrators WHERE ([Administrators].[id] = #{params[:id]})");
sql.delete("DELETE FROM Administrators WHERE ([Administrators].[id] = #{params[:id]})");
sql.commit_db_transaction
performs the operation as expected.
UPDATE4:
This also works:
Administrators.delete(params[:id])
UPDATE5:
Alright, so now CRUD works between Extjs and SQL server. But it's an ugly hack (the update operation especially) and I'd love some insight on how to do this more cleanly:
# POST /administrators
def create
@administrator = Administrators.new(params[:administrators])
@administrator.ID = Administrators.all.length+1
respond_to do |format|
format.html
format.ext_json {render :json => @administrator.to_ext_json(:success => @administrator.save!)}
end
end
# PUT /administrators/1
def update
attrs_to_update = ""
params[:administrators].each {|k,v| attrs_to_update += "#{k} = \'#{v}\', "}
attrs_to_update = attrs_to_update.strip.chomp(",")
sql = ActiveRecord::Base.connection()
sql.begin_db_transaction
sql.execute("SELECT * FROM Administrators WHERE ([Administrators].[id] = #{params[:id]})");
sql.execute("UPDATE Administrators SET #{attrs_to_update} WHERE ([Administrators].[id] = #{params[:id]})");
sql.commit_db_transaction
render :json => @administrator.to_ext_json(:success => @administrator.update_attributes!(params[:administrators]))
end
# DELETE /administrators/1
def destroy
Administrators.delete(params[:id])
head :ok
end
Any thoughts on how to clean this up? Or again why it wouldn't be working out of the box in the first place? :)
BUMP:
Really? Somebody's got to have tried this...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这不是这个问题的一个很好的答案,但我认为这是底线:
This is not a great answer to this question, but I think it's the bottom line: