根据其他列中的值添加PostgreSQL列约束

时间:2018-08-31 17:30:43

标签: sql postgresql

我有一张桌子:

CREATE TABLE ProjectCreationTasks 
(
    Id           text NOT NULL PRIMARY KEY,
    ProjectName  text,
    ProjectCode  text,
    DenialReason text
);

管理员可以批准或拒绝项目创建请求。为了批准,管理员同时设置了ProjectName和ProjectCode。要拒绝,管理员设置DenialReason。

如何添加这样的约束:

  1. NameCodeReason可以同时为空

  2. 如果NameCode都具有值,则Reason必须为空

  3. 如果Reason有一个值,那么NameCode都必须为空

谢谢。

2 个答案:

答案 0 :(得分:1)

您可以使用void set_i_bit(char* mask, int i) { int field_num = floor(i/8); int bit_num = i %8; mask[field_num] = (1 << bit_num) | mask[field_num]; } int write_sparse_with_bitmask(vector<float> arr, ofstream* fout) { int mx_sz = arr.size() - 1; float tol = 0.5; char* mask = 0; for(int i = arr.size() -1; i>=0; i-=1) { if (fabs(arr[i]) > tol) break; mx_sz = i; } int sprse_cnt = 0; for(int i = 0; i<=mx_sz; i+=1) { if (fabs(arr[i]) < tol) sprse_cnt++; } int bitmask_sz = ceil(mx_sz/8); if (sprse_cnt*sizeof(int16_t) + sizeof(int16_t) > bitmask_sz) { cout<<"ALLOCATED"<<endl; mask = new char[bitmask_sz]; for (int i =0; i<bitmask_sz; i++) mask[i] = 0; for(int i = 0; i<=mx_sz; i+=1) { if (fabs(arr[i]) > coef_tol) { set_i_bit(mask, i); } } } else { bitmask_sz = 0; } uint16_t sz = mx_sz + 1; uint16_t bt_msk = bitmask_sz + 1; char flag = 0; if (bitmask_sz > 0) { flag = flag | 1; } fout->write((char*)&sz, sizeof(uint16_t)); fout->write((char*)&flag, sizeof(char)); int w_size = sizeof(uint16_t) + sizeof(char); if (flag & 1) { fout->write((char*)&bt_msk, sizeof(uint16_t)); fout->write(mask, sizeof(char)*bt_msk); cout<<"DEALLOCATING"<<endl; delete [] mask; cout<<"THIS DOESN'T PRINT"<<endl; w_size += sizeof(uint16_t) + sizeof(char)*bt_msk; } for(int i = 0; i<=mx_sz; i+=1) { if (fabs(arr[i]) > tol || !(flag & 1)) { int16_t vl = arr[i]; fout->write((char*) &vl, sizeof(int16_t)); w_size += sizeof(int16_t); } } return w_size; } 约束来实现这种逻辑:

CHECK

DBFiddle Demo

答案 1 :(得分:1)

根据我的评论修改,Lukasz Szozda的回答是正确的(问题陈述有些含糊)。可能更难阅读的较短的等效子句是

CONSTRAINT my_constraint CHECK
((ProjectName IS NULL = ProjectCode IS NULL) -- go together
    AND (ProjectCode IS NULL OR DenialReason IS NULL) -- allow both NULL but disallow both NOT NULL
);