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

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

go 插入復合類型數(shù)組不支持的類型

go 插入復合類型數(shù)組不支持的類型

Go
牛魔王的故事 2023-08-14 15:10:07
sqlCREATE TABLE public.tiantang_page (    href varchar NOT NULL,    status int4 NOT NULL,    description varchar NOT NULL,    urls url[] NULL);CREATE TYPE url AS (    url varchar,    status int4);插入復合類型數(shù)組type url  struct {    url string    status int }    var urls [1]url    urls[0] = url{        url:    "",        status: 0,    }    update := "UPDATE \"public\".\"tiantang_page\" SET \"urls\"=$1 where \"href\"=$2;"    r, err := db.Exec(update, pq.Array(urls),href)    if err != nil {        log.Fatal(err)    }錯誤sql:轉換參數(shù) $1 類型:不支持的類型 parsetest.url,一個結構圖書館https://godoc.org/github.com/lib/pq
查看完整描述

2 回答

?
鴻蒙傳說

TA貢獻1865條經(jīng)驗 獲得超7個贊

請注意,. 不完全支持自定義復合類型lib/pq。


如果您想要的只是能夠存儲 url,那么最簡單的方法是driver.Valuer在url類型上實現(xiàn)接口,然后像使用它一樣使用它pq.Array:


func (u url) Value() (driver.Value, error) {

    return fmt.Sprintf("(%s,%d)", u.url, u.status), nil

}


// ...

r, err := db.Exec(update, pq.Array(urls), href)

有關更多信息,請訪問:https://github.com/lib/pq/issues/544


請注意,我沒有嘗試過使用數(shù)組,僅使用切片,因此您可能必須從使用數(shù)組切換到使用切片,即而不是var urls [1]url使用var urls = make([]url, 1).


如果您還希望能夠從數(shù)據(jù)庫檢索 url 數(shù)組,那么您必須實現(xiàn)該sql.Scanner接口,但是這里pq.Array不太可靠,您必須在切片類型上實現(xiàn)掃描儀并執(zhí)行全部自己解析。


請注意,復合類型的一般格式是(val1, val2, ...),必須在包含逗號或括號的值兩邊加上雙引號。例如,要構造 url 類型的值,您可以使用文字表達式:(http://example.com,4)。文檔中的更多信息。


復合類型數(shù)組的格式為,請{"(val1, val2, ...)" [, ...]}注意,在這種情況下,如果您需要在需要轉義它們的值兩邊加上雙引號。例如{"(http://example.com,4)","(\"http://example.com/?list=foo,bar,baz\",3)"}


正如您所看到的,復合類型中的數(shù)據(jù)越復雜,解析也就越復雜。


這是一個粗略的示例(不處理帶引號的值):

type urlslice []url


func (s *urlslice) Scan(src interface{}) error {

    var a []byte // the pq array as bytes

    switch v := src.(type) {

    case []byte:

        a = v

    case string:

        a = []byte(v)

    case nil:

        *s = nil

        return nil

    default:

        return fmt.Errorf("urlslice.Scan unexpected src type %T", src)

    }


    a = a[1 : len(a)-1] // drop curly braces

    for i := 0; i < len(a); i++ {

        if a[i] == '"' && (len(a) > (i+1) && a[i+1] == '(') { // element start?

            i += 2 // move past `"(`

            j := i // start of url.url

            u := url{}


            for ; i < len(a) && a[i] != ','; i++ {

            }

            u.url = string(a[j:i])


            i += 1 // move past `,`

            j = i  // start of url.status

            for ; i < len(a) && a[i] != ')'; i++ {

            }

            i64, err := strconv.ParseInt(string(a[j:i]), 10, 64)

            if err != nil {

                return err

            }

            u.status = int(i64)

            *s = append(*s, u)


            i += 2 // move past `)",`

        }

    }

    return nil

}

為了完整起見,這里是切片類型實現(xiàn)的 Valuer 接口,同樣不處理可能需要它的值的正確引用:


func (s urlslice) Value() (driver.Value, error) {

    data := []byte{'{'}

    for _, url := range s {

        data = append(data, '"', '(')

        data = append(data, []byte(url.url)...)

        data = append(data, ',')

        data = strconv.AppendInt(data, int64(url.status), 10)

        data = append(data, ')', '"', ',')

    }

    data[len(data)-1] = '}' // replace last ',' with '}' to close the array

    return data, nil

}

通過urlslice直接實現(xiàn)這兩個接口,您可以停止使用pq.Array.


var urls = urlslice{{

    url:    "http://example.com",

    status: 4,

}}

update := `UPDATE "public"."tiantang_page" SET "urls"=$1 where "href"=$2`

r, err := db.Exec(update, urls, href)

if err != nil {

    log.Fatal(err)

}


var urls2 urlslice

selurls := `SELECT "urls" FROM "public"."tiantang_page" where "href" = $1`

if err := db.QueryRow(selurls, href).Scan(&urls2); err != nil {

     log.Fatal(err)

}

請記住,上述兩個示例僅應被視為解決此問題的方向的提示。這兩個示例不僅不完整,因為它們不處理帶引號的值,而且它們也不是非常優(yōu)雅的實現(xiàn)。


查看完整回答
反對 回復 2023-08-14
?
心有法竹

TA貢獻1866條經(jīng)驗 獲得超5個贊

相當完整的復合文字解析器:


type parseState int     


const ( 

        state_initial     parseState = iota // start

        state_value_start                   // no bytes read from value yet

        state_value                         // unquoted value

        state_quoted                        // inside quote

        state_value_end                     // after a close quote

        state_end                           // after close paren

)


func parseComposite(in []byte) ([]string, error) {

        state := state_initial   

        ret := []string{}

        val := []byte{}      


        for _, b := range in {

                switch state {                       


                case state_initial:               

                        if b != '(' {

                                return nil, fmt.Errorf("initial character not ')': %v", in)

                        } else {

                                state = state_value_start

                        }


                case state_value_start:

                        if b == '"' {

                                state = state_quoted       

                                continue

                        } 

                        fallthrough


                case state_value:

                        if b == ',' {       

                                ret = append(ret, string(val))

                                val = nil

                                state = state_value_start    

                        } else if b == ')' {

                                ret = append(ret, string(val))

                                val = nil

                                state = state_end       

                        } else {                                                                                                                      

                                val = append(val, b) 

                        }


                case state_quoted:

                        if b == '"' {      

                                ret = append(ret, string(val))

                                val = nil

                                state = state_value_end

                        } else {  

                                val = append(val, b)          

                        }   


                case state_value_end:

                        if b == ',' {

                                state = state_value_start

                        } else if b == ')' {    

                                state = state_end

                        } else {          

                                return nil, fmt.Errorf("invalid delimiter after closing quote: %v", in)

                        }


                case state_end:

                        return nil, fmt.Errorf("trailing bytes: %v", in)

                }        

        }                                             


        if state != state_end {                

                return nil, fmt.Errorf("unterminated value: %v", in)

        }                                   


        return ret, nil                

}    


查看完整回答
反對 回復 2023-08-14
  • 2 回答
  • 0 關注
  • 140 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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