第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 pq 和 Postgres 對約束進(jìn)行適當(dāng)?shù)腻e誤處理

使用 pq 和 Postgres 對約束進(jìn)行適當(dāng)?shù)腻e誤處理

Go
開心每一天1111 2021-12-07 15:12:31
我目前正在使用pqGo的lib 與我的 PostgreSQL 數(shù)據(jù)庫進(jìn)行通信。事實證明,錯誤檢查比預(yù)期的要困難一些。描述我的問題的最簡單方法是通過一個示例場景。想象一個網(wǎng)絡(luò)表單:Username  ________Email     ________Voucher   ________Password  ________一個粗略的模式:username VARCHAR(255) UNIQUE NOT NULL,email VARCHAR(255) UNIQUE NOT NULL,voucher VARCHAR(255) UNIQUE NOT NULL,password VARCHAR(255) NOT NULL暫時忽略假定的純文本密碼。如果有人提交表單,我可以進(jìn)行所有驗證以驗證諸如長度/允許的字符/等約束?,F(xiàn)在要放到數(shù)據(jù)庫中了,所以我們寫一個準(zhǔn)備好的語句并執(zhí)行它。如果驗證正確完成,唯一可能真正出錯的是UNIQUE約束。如果有人試圖輸入現(xiàn)有的用戶名,database/sql 將觸發(fā)一個錯誤。我的問題是我不知道如何處理該錯誤并從(應(yīng)該是)可恢復(fù)的錯誤中恢復(fù)。pq對此提供了一些支持,但返回的內(nèi)容似乎仍然存在歧義。我可以看到兩種解決方案,這兩種解決方案對我來說都不是特別有吸引力:SERIALIZABLE在插入之前檢查每個表單值的事務(wù)。或者,對 pq 錯誤結(jié)構(gòu)進(jìn)行某種形式的解析。是否有實現(xiàn)這樣一個系統(tǒng)的通用模式?我希望能夠?qū)τ脩粽fSorry that username exists而不是Sorry something bad happened作為旁注,PostgreSQL 文檔指出:模式名稱、表名稱、列名稱、數(shù)據(jù)類型名稱和約束名稱的字段僅針對有限數(shù)量的錯誤類型提供;見 附錄 A。但是鏈接頁面對于數(shù)據(jù)庫對象中返回的值不是很有幫助。
查看完整描述

1 回答

?
幕布斯6054654

TA貢獻(xiàn)1876條經(jīng)驗 獲得超7個贊

如果驗證正確完成,唯一可能真正出錯的是 UNIQUE 約束。


不,客戶可能缺乏足夠的權(quán)限,客戶可能輸入了不是正確密碼的有效密碼,客戶可能輸入了屬于不同客戶的有效憑證等。


使用“在插入之前檢查每個表單值的 SERIALIZABLE 事務(wù)”沒有意義。只需插入數(shù)據(jù),并捕獲錯誤。


至少,您的代碼需要檢查并響應(yīng) C(代碼)字段,該字段始終存在于錯誤結(jié)構(gòu)中。您不需要解析錯誤結(jié)構(gòu),但確實需要閱讀它。


如果違反了唯一約束,PostgreSQL 將在代碼字段中返回 SQL 狀態(tài) 23505。它還將返回違反的第一個約束的名稱。它不返回列名,可能是因為唯一約束可以包含多個列。


您可以通過查詢 information_schema 視圖來選擇約束引用的列。


這是您的表格的簡單版本。


create table test (

  username VARCHAR(255) UNIQUE NOT NULL,

  email VARCHAR(255) UNIQUE NOT NULL,

  voucher VARCHAR(255) UNIQUE NOT NULL,

  password VARCHAR(255) NOT NULL

);


insert into test values ('msherrill', 'me@example.com', 'a', 'wibble');

這個快速而骯臟的 go 程序再次插入同一行。它違反了每一個唯一的約束。


package main


import (

    "github.com/lib/pq"

    "database/sql"

    "fmt"

    "log"

)


func main() {

    db, err := sql.Open("postgres", "host=localhost port=5435 user=postgres password=xxxxxxxx dbname=scratch sslmode=disable")

    if err != nil {

        log.Fatal(err)

    }


    rows, err := db.Exec("insert into public.test values ('msherrill', 'me@example.com', 'a', 'wibble');")

    if err, ok := err.(*pq.Error); ok {

        fmt.Println("Severity:", err.Severity)

        fmt.Println("Code:", err.Code)

        fmt.Println("Message:", err.Message)

        fmt.Println("Detail:", err.Detail)

        fmt.Println("Hint:", err.Hint)

        fmt.Println("Position:", err.Position)

        fmt.Println("InternalPosition:", err.InternalPosition)

        fmt.Println("Where:", err.Where)

        fmt.Println("Schema:", err.Schema)

        fmt.Println("Table:", err.Table)

        fmt.Println("Column:", err.Column)

        fmt.Println("DataTypeName:", err.DataTypeName)

        fmt.Println("Constraint:", err.Constraint)

        fmt.Println("File:", err.File)

        fmt.Println("Line:", err.Line)

        fmt.Println("Routine:", err.Routine)

    }

   fmt.Println(rows)

}

這是輸出。


嚴(yán)重性:錯誤

代碼:23505

消息:重復(fù)鍵值違反唯一約束“test_username_key”

詳細(xì)信息:密鑰(用戶名)=(msherrill)已經(jīng)存在。

暗示: 

位置: 

內(nèi)部位置: 

在哪里: 

架構(gòu):公共

表:測試

柱子: 

數(shù)據(jù)類型名稱: 

約束:test_username_key

文件:nbtinsert.c

線路:406

例程:_bt_check_unique

您有架構(gòu)、表和約束名稱。您大概也知道數(shù)據(jù)庫(目錄)名稱。使用這些值從 information_schema 視圖中選擇模式、表和列名稱。你很幸運;在這種情況下,您只需要一個視圖。


select table_catalog, table_schema, table_name, column_name 

from information_schema.key_column_usage

where 

    table_catalog = 'scratch' and          -- Database name

    table_schema = 'public' and            -- value returned by err.Schema

    table_name = 'test' and                -- value returned by err.Table

    constraint_name = 'test_username_key'  -- value returned by err.Constraint

order by constraint_catalog, constraint_schema, constraint_name, ordinal_position;


查看完整回答
反對 回復(fù) 2021-12-07
  • 1 回答
  • 0 關(guān)注
  • 210 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號