根据BigQuery schema documentation,BigQuery支持以下列模式:可空,必需和重复。 有什么方法可以使字段(类型为“记录”)同时为必需字段和重复字段?
目前,我有:
public int[] ReadHoldingRegisters(int startingAddress, int quantity)
{
if (debug) StoreLogData.Instance.Store("FC3 (Read Holding Registers from Master device), StartingAddress: "+ startingAddress+", Quantity: " +quantity, System.DateTime.Now);
transactionIdentifierInternal++;
if (serialport != null)
if (!serialport.IsOpen)
{
if (debug) StoreLogData.Instance.Store("SerialPortNotOpenedException Throwed", System.DateTime.Now);
throw new EasyModbus.Exceptions.SerialPortNotOpenedException("serial port not opened");
}
if (tcpClient == null & !udpFlag & serialport == null)
{
if (debug) StoreLogData.Instance.Store("ConnectionException Throwed", System.DateTime.Now);
throw new EasyModbus.Exceptions.ConnectionException("connection error");
}
if (startingAddress > 65535 | quantity >125)
{
if (debug) StoreLogData.Instance.Store("ArgumentException Throwed", System.DateTime.Now);
throw new ArgumentException("Starting address must be 0 - 65535; quantity must be 0 - 125");
}
int[] response;
this.transactionIdentifier = BitConverter.GetBytes((uint)transactionIdentifierInternal);
this.protocolIdentifier = BitConverter.GetBytes((int) 0x0000);
this.length = BitConverter.GetBytes((int)0x0006);
this.functionCode = 0x03;
this.startingAddress = BitConverter.GetBytes(startingAddress);
this.quantity = BitConverter.GetBytes(quantity);
Byte[] data = new byte[]{ this.transactionIdentifier[1],
this.transactionIdentifier[0],
this.protocolIdentifier[1],
this.protocolIdentifier[0],
this.length[1],
this.length[0],
this.unitIdentifier,
this.functionCode,
this.startingAddress[1],
this.startingAddress[0],
this.quantity[1],
this.quantity[0],
this.crc[0],
this.crc[1]
};
crc = BitConverter.GetBytes(calculateCRC(data, 6, 6));
data[12] = crc[0];
data[13] = crc[1];
if (serialport != null)
{
dataReceived = false;
bytesToRead = 5 + 2 * quantity;
// serialport.ReceivedBytesThreshold = bytesToRead;
serialport.Write(data, 6, 8);
if (debug)
{
byte [] debugData = new byte[8];
Array.Copy(data, 6, debugData, 0, 8);
if (debug) StoreLogData.Instance.Store("Send Serial-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now);
}
if (SendDataChanged != null)
{
sendData = new byte[8];
Array.Copy(data, 6, sendData, 0, 8);
SendDataChanged(this);
}
data = new byte[2100];
readBuffer = new byte[256];
DateTime dateTimeSend = DateTime.Now;
byte receivedUnitIdentifier = 0xFF;
while (receivedUnitIdentifier != this.unitIdentifier & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout))
{
while (dataReceived == false & !((DateTime.Now.Ticks - dateTimeSend.Ticks) > TimeSpan.TicksPerMillisecond * this.connectTimeout))
System.Threading.Thread.Sleep(1);
data = new byte[2100];
Array.Copy(readBuffer, 0, data, 6, readBuffer.Length);
receivedUnitIdentifier = data[6];
}
if (receivedUnitIdentifier != this.unitIdentifier)
data = new byte[2100];
else
countRetries = 0;
}
else if (tcpClient.Client.Connected | udpFlag)
{
if (udpFlag)
{
UdpClient udpClient = new UdpClient();
IPEndPoint endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), port);
udpClient.Send(data, data.Length-2, endPoint);
portOut = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port;
udpClient.Client.ReceiveTimeout = 5000;
endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddress), portOut);
data = udpClient.Receive(ref endPoint);
}
else
{
stream.Write(data, 0, data.Length-2);
if (debug)
{
byte [] debugData = new byte[data.Length-2];
Array.Copy(data, 0, debugData, 0, data.Length-2);
if (debug) StoreLogData.Instance.Store("Send ModbusTCP-Data: "+BitConverter.ToString(debugData) ,System.DateTime.Now);
}
if (SendDataChanged != null)
{
sendData = new byte[data.Length-2];
Array.Copy(data, 0, sendData, 0, data.Length-2);
SendDataChanged(this);
}
Console.WriteLine("The data I get is " + BitConverter.ToString(data));
data = new Byte[256];
int NumberOfBytes = stream.Read(data, 0, data.Length);
if (ReceiveDataChanged != null)
{
receiveData = new byte[NumberOfBytes];
Array.Copy(data, 0, receiveData, 0, NumberOfBytes);
if (debug) StoreLogData.Instance.Store("Receive ModbusTCP-Data: " + BitConverter.ToString(receiveData), System.DateTime.Now);
ReceiveDataChanged(this);
}
}
}
if (data[7] == 0x83 & data[8] == 0x01)
{
if (debug) StoreLogData.Instance.Store("FunctionCodeNotSupportedException Throwed", System.DateTime.Now);
throw new EasyModbus.Exceptions.FunctionCodeNotSupportedException("Function code not supported by master");
}
if (data[7] == 0x83 & data[8] == 0x02)
{
if (debug) StoreLogData.Instance.Store("StartingAddressInvalidException Throwed", System.DateTime.Now);
throw new EasyModbus.Exceptions.StartingAddressInvalidException("Starting address invalid or starting address + quantity invalid");
}
if (data[7] == 0x83 & data[8] == 0x03)
{
if (debug) StoreLogData.Instance.Store("QuantityInvalidException Throwed", System.DateTime.Now);
throw new EasyModbus.Exceptions.QuantityInvalidException("quantity invalid");
}
if (data[7] == 0x83 & data[8] == 0x04)
{
if (debug) StoreLogData.Instance.Store("ModbusException Throwed", System.DateTime.Now);
throw new EasyModbus.Exceptions.ModbusException("error reading");
}
if (serialport != null)
{
crc = BitConverter.GetBytes(calculateCRC(data, (ushort)(data[8]+3), 6));
if ((crc[0] != data[data[8]+9] | crc[1] != data[data[8]+10])& dataReceived)
{
if (debug) StoreLogData.Instance.Store("CRCCheckFailedException Throwed", System.DateTime.Now);
if (NumberOfRetries <= countRetries)
{
countRetries = 0;
throw new EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed");
}
else
{
countRetries++;
return ReadHoldingRegisters(startingAddress, quantity);
}
}
else if (!dataReceived)
{
if (debug) StoreLogData.Instance.Store("TimeoutException Throwed", System.DateTime.Now);
if (NumberOfRetries <= countRetries)
{
countRetries = 0;
throw new TimeoutException("No Response from Modbus Slave");
}
else
{
countRetries++;
return ReadHoldingRegisters(startingAddress, quantity);
}
}
}
response = new int[quantity];
for (int i = 0; i < quantity; i++)
{
byte lowByte;
byte highByte;
highByte = data[9+i*2];
lowByte = data[9+i*2+1];
data[9+i*2] = lowByte;
data[9+i*2+1] = highByte;
response[i] = BitConverter.ToInt16(data,(9+i*2));
}
return (response);
}
答案 0 :(得分:1)
对于数组,不支持REQUIRED。 参见DDL reference:
(...)支持对非ARRAY类型的可选NOT NULL约束。
column_schema :=
{simple_type [NOT NULL] |
STRUCT<field_list> [NOT NULL] |
ARRAY<array_element_schema>}
[OPTIONS(column_option_list)]
因此,仅支持简单类型和STRUCT / RECORD
不过,您可以发起功能请求:https://issuetracker.google.com/issues?q=componentid:187149