iT邦幫忙

0

SQL語法,修改資料表內容問題

現有資料表A與資料表B,比對A.003=B.006 and A.001<>B.001後,出現5000多筆資料,我要怎麼把B.001的內容改成與A.001的內容一樣呢??(說明:A資料表為客戶資料,B資料表為客戶聯絡人資料,一個客戶會有多個聯絡人,A.001與B.001就是客戶編號,A.003與B.006是客戶公司名稱,由於客戶編碼有變更過,造成A.B兩表客戶公司名稱一樣,但編號不一樣的狀況,所以要將客戶名稱相同但編碼不同的直接改成相同)

sorry..最近忙翻..到現在才來選解答。

To:賽大
最後決定自己用手改了
功力不到..還是一步一步來吧Orz

謝謝大家熱心的回答
3Q~~

2 個回答

6
賽門
iT邦超人 1 級 ‧ 2011-04-22 14:34:51
最佳解答
&lt;pre class="c" name="code">UPDATE B SET B.001 = A.001 
  FROM B INNER JOIN A ON A.003 = B.006 WHERE A.001 &lt;> B.001
看更多先前的回應...收起先前的回應...

它說..0個資料列受影響耶>"<

是不是我要先select把那5000筆資料查出後再改?

賽門 iT邦超人 1 級 ‧ 2011-04-22 15:07:48 檢舉

再試看看...

&lt;pre class="c" name="code">UPDATE B SET B.001 = A.001 FROM A WHERE A.003 = B.006

如果這樣可以...那

&lt;pre class="c" name="code">UPDATE B SET B.001 = A.001 FROM B INNER JOIN A ON A.003 = B.006

應該也可以.

如果再不行, 就用Cursor來做吧.... 我再把程式碼PO上來

出現..."訊息 2627,層級 14,狀態 1,行 1
違反 PRIMARY KEY 條件約束 'PK_COPMD'。無法在物件 'dbo.COPMD' 中插入重複的索引鍵。
陳述式已經結束。"

是不是我後來補充的那段造成的@@a

賽門 iT邦超人 1 級 ‧ 2011-04-22 15:15:45 檢舉
&lt;pre class="c" name="code">DECLARE @A001 NVARCHAR(20), @A003 NVARCHAR(200)

SET @A001 = ''
SET @A003 = ''
DECLARE A_Loop CURSOR FOR
    SELECT A.001, A.003 FROM A, B WHERE A.003 = B.006 AND A.001 &lt;> B.001
FOR READ ONLY

OPEN A_Loop
FETCH NEXT FROM A_Loop INTO @A001, @A003
WHILE @@FETCH_STATUS = 0 BEGIN
    UPDATE B SET B.001 = @A001 WHERE B.006 = @A003
    FETCH NEXT FROM A_Loop INTO @A001, @A003
END
CLOSE A_Loop
DEALLOCATE A_Loop
賽門 iT邦超人 1 級 ‧ 2011-04-22 15:17:40 檢舉

aenbishyar提到:
違反 PRIMARY KEY 條件約束 'PK_COPMD'

這是因為在B.001欄位中已經有相同的客戶編號存在了...不能有兩個相同的客戶編號

這是先定義一個空白欄位,放入值後再回寫?

還是一樣耶>"<..出現"違反 PRIMARY KEY …"這段錯誤訊息>"<

我想樓主要先拿定主意(搞清楚)
B001到底是"聯絡人編號"還是"客戶編號"?

如果B001是聯絡人編號
那就應該有另一個欄位是存放"客戶編號"(在B資料表中會重覆)

如果B001是客戶編號
那麼應該會有類似“序號”的欄位
用以識別”同一個客戶的多個連絡人”

提供一個最快最有效的做法
就是
將兩個資料表的table schema貼上來
再各附上各幾筆資料當範例

那麼simon大大就可以很快地
解決你的問題了飛

賽門 iT邦超人 1 級 ‧ 2011-04-22 15:34:50 檢舉

aenbishyar提到:
先定義一個空白欄位

您用的SQL Server嗎?
您會使用SSMS嗎?
先用SSMS把B表的Promary Key拿掉....然後...

&lt;pre class="c" name="code">1. UPDATE B SET 001 = 'X'
2. UPDATE B SET B.001 = A.001 FROM B INNER JOIN A ON A.003 = B.006

接下來再把B表中001欄位內容是'X'的, 重新編號...
再把B表的Primary Key建回來.

希望您已經先把B表備份了.

aenbishyar提到:
違反 PRIMARY KEY …"這段錯誤訊息

你可以找出PRIMARY KEY是指定在那些欄位嗎?

我不會用SSMS>"<
我只學過一學期的資料庫,老師光解釋資料表間的關聯就花半學期多了吧@@|||
所以我都是從網路湊出來語法的>"<

解說一下定義

COPMA 為客戶資料表
MA001 為客戶編號
MA003 為客戶名稱
COPMD 為客戶聯絡人資料表
MD001 為客戶編號
MD002 為聯絡人序號
MD006 為客戶名稱

MD001 與 MD002為PRIMARY KEY

賽門 iT邦超人 1 級 ‧ 2011-04-22 16:47:29 檢舉

看來是在幫忙寫作業了....請版大研究一下SSMS, 照我說的解除Primary Key再建Key的方式來做吧...

我不是在寫作業!如果寫作業我就慢慢研究就好了Orz
是公司要用的啦..寫作業怎麼可能有5000筆錯誤>"<

SSMS要安裝程式嗎?要版權嗎?如果要的話..我想我們公司是不會買的啦>"<

總裁 iT邦好手 1 級 ‧ 2011-04-22 17:54:31 檢舉

通常PK欄位是不能UPDATE的, 所以您要先想辦法把PK限制拿掉, 再去UPDATE
, 不然不會成功的.

不會吧!!我要改的是我們ERP的資料庫耶>"<..所以..是要寫程式拿掉嗎??我有向ERP廠商提出問題..客服的回覆是"我是客服,不懂SQL語法"..我請她問程式撰寫人員,幫忙寫SQL語法,但客服人員不肯..只好拜託大大了>"<

aenbishyar提到:
COPMA 為客戶資料表
MA001 為客戶編號
MA003 為客戶名稱
COPMD 為客戶聯絡人資料表
MD001 為客戶編號
MD002 為聯絡人序號
MD006 為客戶名稱

以這種schema來看
MD006 比較像是聯絡人姓名而不是客戶名稱
如果MD006真的要放客戶名稱
那還不如放客戶編號比較不會錯亂

話又說回來
ERP廠商設計的Table
如果沒有相當的把握
自已去改資料實在不是件好事
更別說是改Key值了

如果真的要改
那就照simon大大的方式去改
但是記得資料要先備份(要可以恢復回來)

至於SMSS倒是小事
只要你有權限以及可以下SQL指令的地方的話
移除Primary key指令如下

&lt;pre class="c" name="code">
/* For SQL Server/Oracle/MS ACCESS */
ALTER TABLE Table1
DROP CONSTRAINT PK_Table1_Col1
GO

/* For MySql */
ALTER TABLE Table1
DROP PRIMARY KEY
GO

以上提供參考
祝好運...

以下是我猜測的另一個可能
如果MD006真的是客戶名稱而不是連絡人名稱
那麼MD001應該是
"主要的客戶編號"而不是"MD006的客戶編號"

講不太清楚,用實際的資料看
這是原來的資料
左方是客戶資料
右方是“客戶的聯絡人資料”
是一對多的關係

以蟹堡王餐廳來看
他有三個連絡人,即另外三個客戶名稱
而這三筆資料的MD001都相同
不是自已的客戶編號
全部都是蟹堡王的客戶編號(c002)

如果你真的去改了MD001
可能會變成如下

此時可以看出兩筆賣當勞的
MD001, MD002 都完全相同
即會造成違反PRIMARY KEY CONSTRAINT的狀況

.....

祝好運

TO:antijava
目前的狀況的確如你所說沒錯@@
真的是MD001中有許多重覆值
因為是一個MA對很多個MD

目前我們的公司資料就是如此@@:

COPMA COPMD
MA001 MA003 MD001 MD002 MD006 MD007
C001 麥當勞 C001 001 麥當勞 麥小姐
C002 肯德雞 C002 001 肯德基 肯先生
C003 頂呱呱 C002 002 肯德基 德小姐
C004 摩斯 C002 003 肯德基 基金
C003 001 摩斯 摩斯堡
C003 002 摩斯 摩太太
C004 001 頂呱呱 頂好吃
C004 002 頂呱呱 呱寶
C004 003 頂呱呱 分店
C004 004 頂呱呱 店長

所以..
是沒辦法改的囉?@@a

賽門 iT邦超人 1 級 ‧ 2011-04-26 13:15:51 檢舉

aenbishyar提到:
我要改的是我們ERP的資料庫耶

那家的ERP? 那些顧問幫忙導的ERP? 您可以透露一下嗎? 以後遇見了, 就說: 謝謝光臨...然後送出公司大門....

賽門 iT邦超人 1 級 ‧ 2011-04-26 13:28:58 檢舉

還有個解法:

&lt;pre class="c" name="code">CREATE TABLE TEMP01 AS (SELECT * FROM COPMD);
UPDATE TEMP01 B SET B.001 = A.001 FROM COPMA A WHERE A.003 = B.006;
&lt;&lt;檢查TEMP01的資料內容是否OK>>
&lt;&lt;先把COPMD備份>>
DELETE COPMD;
INSERT INTO COMPD(MD001, MD002, MD006, MD007) SELECT MD001, MD002, MD006, MD007 FROM TEMP01;

請注意:

  1. 最後INSERT指令的欄位您要視實際情形調整
  2. 刪資料前先做好備份

最後, 我真的沒有生氣...最近公司正在重新評估ERP系統, 這兩個星期在做專案計劃和最後選商階段, 就沒注意到這個版塊. 希望以上的說明有助於您的工作.
健身

這個語法的意思是,先建一個TEMP01的資料表,將COPMD的東西放入並刪除COPMD,然後直接修改TEMP01內的資料後再放回COPMD??

現在我很不知所措的是..其實COPMA與MD的資料欄有很多個(COPMA欄位到MA122,COPMD欄位到MD017)..我原本是想針對有錯的部份做修改就好..但看了各位大大所提供的方法及回應,只針對錯的部份修改是很難的囉?

我想simon大大的第6列應該改成這樣更好一些

&lt;pre class="c" name="code">
INSERT INTO COMPD SELECT * FROM TEMP01;  

你想只修改錯的欄位,叫做Update
simon大大的方法
是比較偏向所謂的Delete & Define
只要能達到你的目的
應該沒什麼關係吧疑惑

賽門 iT邦超人 1 級 ‧ 2011-04-27 08:50:43 檢舉

aenbishyar提到:
只針對錯的部份修改是很難的囉?

不是這個意思, 因為在ERP系統中處理資料一致性的問題時, 必須要多注意資料表間的關聯.

像您提到的問題, 應該是COPMA和COPMD間的資料發生不一致, 而這在規劃嚴謹的ERP系統中是幾乎很難發生的問題. 而其他參考到這兩個資料表的資料, 是否也有問題, 要一併配合修訂呢? 這是必需要考慮的問題.

而您提問的方式太過於簡略, 所以更要注意會不會誤導您的處理方向, 以致越幫越忙.

但是, 我必須要說, ERP系統一般來講都是公司的營運工具, 這麼重要的環境, 是否找個更專業點的工程師到現場支援, 會更好? 也可以找ERP系統公司來支援, 這樣總比在這裏摸索好的多.

而且更重要的, 您一直沒說明是那種資料庫系統? SQL Server? Oracle? MySQL? 這三種各有不同的做法. 但, 這也已經不是重點, 重點在, 您的ERP系統的資料一致性破壞了.

我是建議您找ERP系統公司來支援處理, 因為一旦資料一致性被破壞了, ERP系統就存在資料問題, 這會造成日後帳上的問題.

因此, 就回應到這裏了, 請您找人到現場協助, 線上求助, 可能不是處理這個問題的好辦法.

以上, 希望對您有些幫助.

2
Albert
iT邦高手 1 級 ‧ 2011-04-22 20:12:27

aenbishyar提到:


COPMA 為客戶資料表
MA001 為客戶編號
MA003 為客戶名稱

COPMD 為客戶聯絡人資料表
MD001 為客戶編號
MD002 為聯絡人序號
MD006 為客戶名稱

MD001 與 MD002為PRIMARY KEY

UPDATE COPMD
SET MD001=MA001 客戶編號
WHERE MD006=MA003 客戶名稱
-->怪怪 怎會去更新客戶編號
改 MD001 客戶編號 ,
系統沒有連動 MD006
應該去改 MD006

這是哪一家的 ERP
幫忙寫一下 Trigger 讓 MD006 連動

全球最大 OpenSource ERP
Skype: Adempiere/Compiere
技術轉移顧問
Albert

@@..若誤導了..致十二萬分歉意@@

看樣子是只能手改了Orz

Albert iT邦高手 1 級 ‧ 2011-04-26 19:00:05 檢舉

simon 大大
ERP 業界 用無意義編號不多
土產最大那ㄧ家都是這樣搞的

方向對了
不需高超技術
UPDATE COPMD
SET MD006=MA003
WHERE MD001=MA001 客戶編號

我要發表回答

立即登入回答