Làm cách nào để đổi tên một cột trong bảng cơ sở dữ liệu SQLite?


296

Tôi sẽ cần đổi tên một vài cột trong một số bảng trong cơ sở dữ liệu SQLite. Tôi biết rằng một câu hỏi tương tự đã được hỏi về stackoverflow trước đây, nhưng nó là dành cho SQL nói chung và trường hợp SQLite không được đề cập.

Từ tài liệu SQLite cho ALTER TABLE , tôi nhận thấy rằng không thể thực hiện một việc "dễ dàng" như vậy (nghĩa là một câu lệnh ALTER TABLE duy nhất).

Tôi đã tự hỏi ai đó biết về một cách SQL chung để làm một việc như vậy với SQLite.


Bạn có thể làm điều đó bằng trình duyệt db cho sqlite khá dễ dàng
Matt G

1
Vui lòng xem xét việc đánh dấu câu trả lời này là stackoverflow
Evan Carroll

Câu trả lời:


66

Điều này vừa được sửa với 2018-09-15 (3.25.0)

Cải tiến ALTER TABLElệnh:

  • Thêm hỗ trợ để đổi tên cột trong bảng bằng ALTER TABLEbảng RENAME COLUMN oldname TO newname.
  • Sửa tính năng đổi tên bảng để nó cũng cập nhật các tham chiếu đến bảng đã đổi tên trong các kích hoạt và dạng xem.

Bạn có thể tìm thấy cú pháp mới được ghi lại dưới ALTER TABLE

Các RENAME COLUMN TOcú pháp thay đổi cột tên của bảng bảng tên vào mới-cột-name. Tên cột được thay đổi cả trong chính định nghĩa bảng và cả trong tất cả các chỉ mục, trình kích hoạt và chế độ xem tham chiếu cột. Nếu thay đổi tên cột sẽ dẫn đến sự mơ hồ ngữ nghĩa trong trình kích hoạt hoặc chế độ xem, thì RENAME COLUMNlỗi không thành công và không có thay đổi nào được áp dụng.

nhập mô tả hình ảnh ở đây Nguồn hình ảnh: https://www.sqlite.org/images/syntax/alter-table-stmt.gif

Thí dụ:

CREATE TABLE tab AS SELECT 1 AS c;

SELECT * FROM tab;

ALTER TABLE tab RENAME COLUMN c to c_new;

SELECT * FROM tab;

bản demo db-fiddle.com


Hỗ trợ Android

Khi viết, API 27 của Android đang sử dụng gói SQLite phiên bản 3.19 .

Dựa trên phiên bản hiện tại mà Android đang sử dụng và bản cập nhật này sắp có phiên bản 3.25.0 của SQLite, tôi sẽ nói rằng bạn phải chờ một chút (khoảng API 33) trước khi hỗ trợ cho việc này được thêm vào Android.

Và thậm chí sau đó, nếu bạn cần hỗ trợ bất kỳ phiên bản nào cũ hơn API 33, bạn sẽ không thể sử dụng phiên bản này.


8
Tôi đang triển khai cho việc di chuyển Android và không may là IntelliJ đang hiển thị cảnh báo rằng đó không phải là lệnh SQL hợp lệ. database.execSQL("ALTER TABLE content RENAME COLUMN archiveCount TO dismissCount"). COLUM được tô màu đỏ và nó nói ĐẾN mong đợi, có 'CỘT' . Thật không may, Android vẫn có trên phiên bản SQLite 3.19 , đó là lý do tại sao điều này không phù hợp với tôi.
Adam Hurwitz

1
đã chỉnh sửa: Tôi đã tìm thấy trên system.data.sqlite.org/index.html/doc/trunk/www/faq.wiki#q1 , rằng 1.0.109.x) thực sự đang sử dụng SQLite 3.24 và System.Data.SQLite sử dụng SQLite 3.25 sẽ được điều chỉnh trong tháng này.
rychlmoj

1
Thật không may, điều này vẫn chưa được thư viện SQLite của Android triển khai . Hy vọng họ sẽ cập nhật sớm.
Adam Hurwitz

3
Tôi đã thêm một phần cho Hỗ trợ Android để ngăn người khác không hy vọng. Dựa trên việc sử dụng SQLite 3.19 hiện tại của Android 27, chúng tôi sẽ phải đợi cho đến khoảng API 33 trước khi tính năng này được thêm vào Android và thậm chí sau đó nó sẽ chỉ được hỗ trợ trên các phiên bản mới nhất. Thở dài.
Joshua Pinter

1
@JoshuaPinter Cảm ơn bạn đã mở rộng câu trả lời của tôi.
Lukasz Szozda

448

Giả sử bạn có một bảng và cần đổi tên "colb" thành "col_b":

Đầu tiên bạn đổi tên bảng cũ:

ALTER TABLE orig_table_name RENAME TO tmp_table_name;

Sau đó tạo bảng mới, dựa trên bảng cũ nhưng với tên cột được cập nhật:

CREATE TABLE orig_table_name (
  col_a INT
, col_b INT
);

Sau đó sao chép nội dung trên từ bảng gốc.

INSERT INTO orig_table_name(col_a, col_b)
SELECT col_a, colb
FROM tmp_table_name;

Cuối cùng, thả bảng cũ.

DROP TABLE tmp_table_name;

Gói tất cả những thứ này trong một BEGIN TRANSACTION;COMMIT;cũng có thể là một ý tưởng tốt.


51
Và đừng quên chỉ số của bạn.
Tom Mayfield

11
Rất quan trọng mã ví dụ ở trên đang thiếu một giao dịch. Bạn nên bọc toàn bộ trong BEGIN / END (hoặc ROLLBACK) để đảm bảo rằng việc đổi tên hoàn thành thành công hoặc hoàn toàn không.
Roger Binns

4
Bất cứ ai muốn làm điều này trong Android đều có thể thực hiện các giao dịch bằng SQLiteDatabase.beginTransaction ()
bmaupin

7
Không có gì trong mã trong câu trả lời sao chép các chỉ số. Tạo một bảng trống và đưa dữ liệu vào đó chỉ sao chép cấu trúc và dữ liệu. Nếu bạn muốn siêu dữ liệu (chỉ mục, khóa ngoại, ràng buộc, v.v.), thì bạn cũng phải đưa ra các câu lệnh để tạo chúng trên bảng thay thế.
Tom Mayfield

17
.schemaLệnh của SQLite có ích để hiển thị CREATE TABLEcâu lệnh tạo bảng hiện có. Bạn có thể lấy đầu ra của nó, sửa đổi khi cần và thực hiện nó để tạo bảng mới. Lệnh này cũng hiển thị các CREATE INDEXlệnh cần thiết để tạo các chỉ mục, sẽ bao gồm các mối quan tâm của Thomas. Tất nhiên, hãy chắc chắn để chạy lệnh này trước khi thay đổi bất cứ điều gì.
Mike DeSimone

56

Tìm hiểu kỹ, tôi tìm thấy công cụ đồ họa đa nền tảng (Linux | Mac | Windows) có tên DB Browser cho SQLite này thực sự cho phép một người đổi tên các cột theo cách rất thân thiện với người dùng!

Chỉnh sửa | Sửa đổi bảng | Chọn bảng | Chỉnh sửa trường. Click click! Voila!

Tuy nhiên, nếu ai đó muốn chia sẻ một cách lập trình để làm điều này, tôi rất vui được biết!


1
Ngoài ra còn có một tiện ích bổ sung Firefox thực hiện điều tương tự , Nhấp chuột phải vào cột bạn muốn đổi tên và chọn "Chỉnh sửa cột".
Jacob Hacker

1
Ngay cả trong openSUSE, nó cũng có sẵn dưới dạng gói: software.opensuse.org/package/sqlitebrowser

Thật kỳ lạ khi nó có rất nhiều phiếu bầu. Chúng ta đang nói về lập trình ở đây (mã). Tại sao bạn thậm chí đăng câu trả lời này ở đây?
dùng25

2
Không có đề cập về cách làm điều này với mã trong câu hỏi của tôi. Tôi chỉ muốn biết cách đổi tên một cột trong SQLite DB.
joce

@joce Em yêu anh !!! (giống như một người anh em) đã giúp tôi thay đổi lĩnh vực này, thì đấy. Tôi đã xuất bảng MS Access sang SQLite và một trong các trường có một chữ số ở phía trước: 3YearLetterSent. Visual Studio đã tạo ra lớp từ bảng nhưng bị nghẹn ở chữ số "3" ở phía trước tên trường. Tôi biết điều này, chỉ là không xem.
JustJohn

53

Mặc dù đúng là không có ALTER COLUMN, nhưng nếu bạn chỉ muốn đổi tên cột, bỏ ràng buộc KHÔNG NULL hoặc thay đổi loại dữ liệu, bạn có thể sử dụng bộ lệnh sau:

Lưu ý: Các lệnh này có khả năng làm hỏng cơ sở dữ liệu của bạn, vì vậy hãy đảm bảo bạn có bản sao lưu

PRAGMA writable_schema = 1;
UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE BOOKS ( title TEXT NOT NULL, publication_date TEXT)' WHERE NAME = 'BOOKS';
PRAGMA writable_schema = 0;

Bạn sẽ cần phải đóng và mở lại kết nối của mình hoặc hút bụi cơ sở dữ liệu để tải lại các thay đổi vào lược đồ.

Ví dụ:

Y:\> sqlite3 booktest  
SQLite version 3.7.4  
Enter ".help" for instructions  
Enter SQL statements terminated with a ";"  
sqlite> create table BOOKS ( title TEXT NOT NULL, publication_date TEXT NOT NULL);  
sqlite> insert into BOOKS VALUES ("NULLTEST",null);  
Error: BOOKS.publication_date may not be NULL  
sqlite> PRAGMA writable_schema = 1; 
sqlite> UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE BOOKS ( title TEXT NOT NULL, publication_date TEXT)' WHERE NAME = 'BOOKS';  
sqlite> PRAGMA writable_schema = 0;  
sqlite> .q  

Y:\> sqlite3 booktest  
SQLite version 3.7.4  
Enter ".help" for instructions  
Enter SQL statements terminated with a ";"  
sqlite> insert into BOOKS VALUES ("NULLTEST",null);  
sqlite> .q  

TÀI LIỆU THAM KHẢO SAU:


pragma writable_schema
Khi pragma này được bật, các bảng SQLITE_MASTER trong đó cơ sở dữ liệu có thể được thay đổi bằng cách sử dụng các câu lệnh UPDATE, INSERT và DELETE thông thường. Cảnh báo: lạm dụng pragma này có thể dễ dàng dẫn đến một tệp cơ sở dữ liệu bị hỏng.

bảng thay đổi
SQLite hỗ trợ một tập hợp con giới hạn của ALTER TABLE. Lệnh ALTER TABLE trong SQLite cho phép người dùng đổi tên bảng hoặc thêm cột mới vào bảng hiện có. Không thể đổi tên một cột, xóa một cột hoặc thêm hoặc xóa các ràng buộc khỏi một bảng.

BẢNG BIỂU TƯỢNG


3
Nguy hiểm, nhưng có lẽ vẫn là câu trả lời thẳng thắn nhất.
Tek

2
Có cực kỳ nhanh - Nguy hiểm chỉ có nghĩa là "Hãy chắc chắn rằng bạn có bản sao lưu trước"

6
Định dạng tệp sqlite rất đơn giản và đó là lý do tại sao thao tác này hợp lệ. Định dạng tệp chỉ có hai bộ thông tin về một bảng: Lệnh CREATE TABLE thực tế dưới dạng văn bản thuần túy và các hàng có giá trị xuất hiện theo thứ tự các trường từ lệnh CREATE. Điều đó có nghĩa là mã sqlite mở cơ sở dữ liệu, nó phân tích từng lệnh CREATE và tự động xây dựng thông tin cột của nó trong bộ nhớ. Vì vậy, bất kỳ lệnh nào làm thay đổi lệnh CREATE theo cách kết thúc với cùng số cột sẽ hoạt động, ngay cả khi bạn thay đổi loại hoặc ràng buộc của chúng.
Thomas Tempelmann

3
@ThomasTempelmann Tuy nhiên, việc thêm các ràng buộc không được thực hiện bởi bộ dữ liệu sẽ dẫn đến các vấn đề vì trình hoạch định truy vấn giả định rằng các ràng buộc đó giữ.
fuz

2
@ThomasTempelmann Loại bỏ các ràng buộc luôn luôn tốt. Thêm các ràng buộc là tốt nếu các ràng buộc được thỏa mãn bởi tất cả các hàng nhưng bạn chắc chắn cần phải kiểm tra.
fuz

18

Gần đây tôi đã phải làm điều đó trong SQLite3 với một bảng có tên các điểm với id colunms , lon, lat . Erroneusly, khi bảng được nhập, các giá trị cho vĩ độ được lưu trữ trong cột lon và ngược lại, do đó, một sửa chữa rõ ràng sẽ là đổi tên các cột đó. Vì vậy, mẹo là:

create table points_tmp as select id, lon as lat, lat as lon from points;
drop table points;
alter table points_tmp rename to points;

Tôi hy vọng điều này sẽ hữu ích cho bạn!


Phương pháp này không sao chép giá trị PK một cách thích hợp và tự động tạo cột hàng ẩn. Không nhất thiết là một vấn đề nhưng muốn chỉ ra điều đó bởi vì nó trở thành một vấn đề đối với tôi.
TPoschel

4
Sẽ không dễ dàng hơn để làm "CẬP NHẬT điểm SET lon = lat, lat = lon;"?
kstep

1
Câu trả lời này không thực hiện quá trình trong thứ tự đúng. Đầu tiên tạo bảng tạm thời và điền vào bảng sau đó hủy bản gốc .
Xeoncross

14

Trích dẫn tài liệu sqlite :

SQLite hỗ trợ một tập hợp con giới hạn của ALTER TABLE. Lệnh ALTER TABLE trong SQLite cho phép người dùng đổi tên bảng hoặc thêm cột mới vào bảng hiện có. Không thể đổi tên một cột, xóa một cột hoặc thêm hoặc xóa các ràng buộc khỏi một bảng.

Tất nhiên những gì bạn có thể làm là, tạo một bảng mới với bố cục mới SELECT * FROM old_tablevà điền vào bảng mới với các giá trị bạn sẽ nhận được.


7

Trước hết, đây là một trong những điều khiến tôi bất ngờ: đổi tên một cột đòi hỏi phải tạo một bảng hoàn toàn mới và sao chép dữ liệu từ bảng cũ sang bảng mới ...

GUI tôi đã sử dụng để thực hiện các hoạt động SQLite là Base . Nó có một cửa sổ Log tiện lợi hiển thị tất cả các lệnh đã được thực thi. Thực hiện đổi tên một cột thông qua Base sẽ tạo ra các cửa sổ nhật ký với các lệnh cần thiết:

Cửa sổ nhật ký cơ sở

Chúng có thể dễ dàng được sao chép và dán vào nơi bạn có thể cần chúng. Đối với tôi, đó là một tệp di chuyển ActiveAndroid . Một điều tuyệt vời nữa là dữ liệu được sao chép chỉ bao gồm các lệnh SQLite, không phải dấu thời gian, v.v.

Hy vọng rằng, điều đó tiết kiệm thời gian của một số người.


FYI, nếu bạn đang sử dụng ActiveAndroid , bạn có thể bỏ qua các dòng BEGIN TRANSACTION;COMMIT;dòng, vì ActiveAndroid tự xử lý nó.
Joshua Pinter

6

TRƯỜNG HỢP 1: SQLite 3.25.0+

Chỉ phiên bản 3.25.0 của SQLite hỗ trợ đổi tên cột. Nếu thiết bị của bạn đáp ứng yêu cầu này, mọi thứ khá đơn giản. Các truy vấn dưới đây sẽ giải quyết vấn đề của bạn:

ALTER TABLE "MyTable" RENAME COLUMN "OldColumn" TO "NewColumn";

CASE 2: SQLite Phiên bản cũ hơn

Bạn phải tuân theo một Cách tiếp cận khác để có được kết quả có thể hơi khó

Ví dụ: nếu bạn có một bảng như thế này:

CREATE TABLE student(Name TEXT, Department TEXT, Location TEXT)

Và nếu bạn muốn thay đổi tên của cột Location

Bước 1: Đổi tên bảng gốc:

ALTER TABLE student RENAME TO student_temp;

Bước 2: Bây giờ tạo một bảng mới studentvới tên cột chính xác:

CREATE TABLE student(Name TEXT, Department TEXT, Address TEXT)

Bước 3: Sao chép dữ liệu từ bảng gốc sang bảng mới:

INSERT INTO student(Name, Department, Address) SELECT Name, Department, Location FROM student_temp;

Lưu ý: Lệnh trên phải là tất cả một dòng.

Bước 4: Thả bảng gốc:

DROP TABLE student_temp;

Với bốn bước này, bạn có thể thay đổi thủ công bất kỳ bảng SQLite nào. Hãy nhớ rằng bạn cũng sẽ cần phải tạo lại bất kỳ chỉ mục, người xem hoặc trình kích hoạt nào trên bảng mới.


1
Cách nâng cấp phiên bản cơ sở dữ liệu sqllite lên 3.29.0 trong studio android tôi đang sử dụng cấp độ api 28.
Phần mềm Nathani

Phiên bản SQLite được xác định bởi thiết bị mà Ứng dụng hoạt động. Nó phụ thuộc vào thiết bị.
Febin Mathew

1
Đối với những người sử dụng sqlite cũ, bốn bước trên không được khuyến khích. Xem phần "Chú ý" tại sqlite.org/lang_altertable.html .
Jeff

3

thay đổi cột bảng <id> thành <_id>

 String LastId = "id";

    database.execSQL("ALTER TABLE " + PhraseContract.TABLE_NAME + " RENAME TO " + PhraseContract.TABLE_NAME + "old");
    database.execSQL("CREATE TABLE " + PhraseContract.TABLE_NAME
    +"("
            + PhraseContract.COLUMN_ID + " INTEGER PRIMARY KEY,"
            + PhraseContract.COLUMN_PHRASE + " text ,"
            + PhraseContract.COLUMN_ORDER  + " text ,"
            + PhraseContract.COLUMN_FROM_A_LANG + " text"
    +")"
    );
    database.execSQL("INSERT INTO " +
            PhraseContract.TABLE_NAME + "("+ PhraseContract.COLUMN_ID +" , "+ PhraseContract.COLUMN_PHRASE + " , "+ PhraseContract.COLUMN_ORDER +" , "+ PhraseContract.COLUMN_FROM_A_LANG +")" +
            " SELECT " + LastId +" , "+ PhraseContract.COLUMN_PHRASE + " , "+ PhraseContract.COLUMN_ORDER +" , "+ PhraseContract.COLUMN_FROM_A_LANG +
            " FROM " + PhraseContract.TABLE_NAME + "old");
    database.execSQL("DROP TABLE " + PhraseContract.TABLE_NAME + "old");

3

Tạo một cột mới với tên cột mong muốn: COLNew.

ALTER TABLE {tableName} ADD COLUMN COLNew {type};

Sao chép nội dung của cột cũ COLOld sang cột mới COLNew.

INSERT INTO {tableName} (COLNew) SELECT {COLOld} FROM {tableName}

Lưu ý: dấu ngoặc là cần thiết trong dòng trên.


2

Như đã đề cập trước đây, có một công cụ Trình duyệt cơ sở dữ liệu SQLite, thực hiện việc này. Lyckily, công cụ này giữ một bản ghi của tất cả các hoạt động được thực hiện bởi người dùng hoặc ứng dụng. Làm điều này một lần và nhìn vào nhật ký ứng dụng, bạn sẽ thấy mã liên quan. Sao chép truy vấn và dán theo yêu cầu. Đã làm cho tôi. Hi vọng điêu nay co ich


2

Từ tài liệu chính thức

Một thủ tục đơn giản và nhanh hơn có thể được sử dụng tùy ý cho một số thay đổi không ảnh hưởng đến nội dung trên đĩa theo bất kỳ cách nào. Quy trình đơn giản sau đây phù hợp để xóa các ràng buộc CHECK hoặc FOREIGN KEY hoặc KHÔNG NULL, đổi tên cột hoặc thêm hoặc xóa hoặc thay đổi giá trị mặc định trên một cột.

  1. Bắt đầu một giao dịch.

  2. Chạy lược đồ PRAGMA_version để xác định số phiên bản lược đồ hiện tại. Số này sẽ cần thiết cho bước 6 dưới đây.

  3. Kích hoạt chỉnh sửa lược đồ bằng PRAGMA writable_schema = ON.

  4. Chạy một câu lệnh UPDATE để thay đổi định nghĩa của bảng X trong bảng sqlite_master: UPDATE sqlite_master SET sql = ... WHERE type = 'table' AND name = 'X';

    Thận trọng: Thực hiện thay đổi đối với bảng sqlite_master như thế này sẽ khiến cơ sở dữ liệu bị hỏng và không thể đọc được nếu thay đổi có lỗi cú pháp. Chúng tôi khuyên bạn nên kiểm tra cẩn thận câu lệnh CẬP NHẬT trên một cơ sở dữ liệu trống riêng trước khi sử dụng nó trên cơ sở dữ liệu chứa dữ liệu quan trọng.

  5. Nếu thay đổi đối với bảng X cũng ảnh hưởng đến các bảng hoặc chỉ mục hoặc trình kích hoạt khác là các khung nhìn trong lược đồ, thì hãy chạy các câu lệnh CẬP NHẬT để sửa đổi các chỉ mục và các khung nhìn của các bảng khác. Ví dụ: nếu tên của một cột thay đổi, tất cả các ràng buộc, kích hoạt, chỉ mục và các khung nhìn liên quan đến cột đó phải được sửa đổi.

    Thận trọng: Một lần nữa, thực hiện các thay đổi đối với bảng sqlite_master như thế này sẽ khiến cơ sở dữ liệu bị hỏng và không thể đọc được nếu thay đổi có lỗi. Kiểm tra cẩn thận toàn bộ quy trình này trên cơ sở dữ liệu kiểm tra riêng trước khi sử dụng nó trên cơ sở dữ liệu chứa dữ liệu quan trọng và / hoặc tạo bản sao dự phòng của cơ sở dữ liệu quan trọng trước khi chạy quy trình này.

  6. Tăng số phiên bản lược đồ bằng PRAGMA lược đồ_version = X trong đó X nhiều hơn số phiên bản lược đồ cũ được tìm thấy trong bước 2 ở trên.

  7. Vô hiệu hóa chỉnh sửa lược đồ bằng PRAGMA writable_schema = OFF.

  8. (Tùy chọn) Chạy PRAGMA vẹn_check để xác minh rằng các thay đổi lược đồ không làm hỏng cơ sở dữ liệu.

  9. Cam kết giao dịch bắt đầu ở bước 1 ở trên.


PRAGMA vẹn_check không nhận bất kỳ lỗi nào với lược đồ.
Graymatter

và vấn đề với điều đó là gì?
Mohammad Yahia

1

Một tùy chọn, nếu bạn cần nó được thực hiện trong một nhúm và nếu cột ban đầu của bạn được tạo với mặc định, là tạo cột mới mà bạn muốn, sao chép nội dung qua nó và về cơ bản là "từ bỏ" cột cũ (nó vẫn ở lại hiện tại, nhưng bạn không sử dụng / cập nhật nó, v.v.)

Ví dụ:

alter table TABLE_NAME ADD COLUMN new_column_name TYPE NOT NULL DEFAULT '';
update TABLE_NAME set new_column_name = old_column_name;
update TABLE_NAME set old_column_name = ''; -- abandon old column, basically

Điều này để lại một cột (và nếu nó được tạo bằng KHÔNG NULL nhưng không có mặc định, thì các phần chèn trong tương lai mà bỏ qua nó có thể thất bại), nhưng nếu đó chỉ là một bảng ném, sự đánh đổi có thể được chấp nhận. Mặt khác, sử dụng một trong những câu trả lời khác được đề cập ở đây hoặc cơ sở dữ liệu khác cho phép đổi tên cột.



-3

sqlite3 yourdb .dump> /tmp/db.txt
chỉnh sửa /tmp/db.txt thay đổi tên cột trong Tạo dòng
sqlite2 yourdb2 </tmp/db.txt
mv / di chuyển yourdb2 yourdb


3
câu trả lời của bạn không cung cấp bất kỳ thông tin nào, một loạt các mã / hướng dẫn nhổ ra mà không có thêm thông tin nào về lý do tại sao bạn nghĩ nó sẽ hoạt động hoặc điều gì sẽ xảy ra nếu bạn chạy nó
RGLSV
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.